2 * Copyright (c) 2004-2009 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 * Modification History
27 * May 13, 2004 Allan Nathanson <ajn@apple.com>
29 * which includes code originally authored by
30 * Robert Ulrich <rulrich@apple.com>
31 * Elizabeth Douglas <elizabeth@apple.com>
32 * Quinn <eskimo1@apple.com>
36 #include <Availability.h>
37 #include <TargetConditionals.h>
38 #include <CoreFoundation/CoreFoundation.h>
39 #include <CoreFoundation/CFRuntime.h>
40 #include <SystemConfiguration/SystemConfiguration.h>
41 #include "SCNetworkConfigurationInternal.h"
42 #include <SystemConfiguration/SCValidation.h>
43 #include <SystemConfiguration/SCPrivate.h>
44 #include "SCPreferencesInternal.h"
45 #include "SCHelper_client.h"
48 #include <EAP8021X/EAPClientProperties.h>
49 #else // !TARGET_OS_IPHONE
50 #ifndef kEAPClientPropUserName
51 #define kEAPClientPropUserName CFSTR("UserName")
53 #ifndef kEAPClientPropUserPasswordKeychainItemID
54 #define kEAPClientPropUserPasswordKeychainItemID CFSTR("UserPasswordKeychainItemID")
56 #endif // !TARGET_OS_IPHONE
58 #include <IOKit/IOKitLib.h>
59 #include <IOKit/IOCFBundle.h>
60 #include <IOKit/IOBSD.h>
61 #include <IOKit/network/IONetworkController.h>
62 #include <IOKit/network/IONetworkInterface.h>
63 #include <IOKit/network/IOEthernetInterface.h> // for kIOEthernetInterfaceClass
64 #include <IOKit/serial/IOSerialKeys.h>
65 #include <IOKit/storage/IOStorageDeviceCharacteristics.h>
66 #include <IOKit/usb/USB.h>
68 #include "dy_framework.h"
70 #ifndef kIODeviceSupportsHoldKey
71 #define kIODeviceSupportsHoldKey "V92Modem"
74 #ifndef kUSBProductString
75 #define kUSBProductString "USB Product Name"
79 #include <mach/mach.h>
81 #include <net/if_types.h>
82 #include <net/route.h>
83 #include <sys/param.h>
84 #include <sys/types.h>
85 #include <sys/socket.h>
87 #include <sys/sysctl.h>
89 #include <NSSystemDirectories.h>
92 static CFStringRef
copy_interface_string (CFBundleRef bundle
, CFStringRef key
, Boolean localized
);
93 static CFStringRef
__SCNetworkInterfaceCopyDescription (CFTypeRef cf
);
94 static void __SCNetworkInterfaceDeallocate (CFTypeRef cf
);
95 static Boolean
__SCNetworkInterfaceEqual (CFTypeRef cf1
, CFTypeRef cf2
);
96 static CFHashCode
__SCNetworkInterfaceHash (CFTypeRef cf
);
116 #if !TARGET_OS_IPHONE
119 #endif // !TARGET_OS_IPHONE
124 const CFStringRef kSCNetworkInterfaceType6to4
= CFSTR("6to4");
125 const CFStringRef kSCNetworkInterfaceTypeBluetooth
= CFSTR("Bluetooth");
126 #if !TARGET_OS_IPHONE
127 const CFStringRef kSCNetworkInterfaceTypeBond
= CFSTR("Bond");
128 #endif // !TARGET_OS_IPHONE
129 const CFStringRef kSCNetworkInterfaceTypeEthernet
= CFSTR("Ethernet");
130 const CFStringRef kSCNetworkInterfaceTypeFireWire
= CFSTR("FireWire");
131 const CFStringRef kSCNetworkInterfaceTypeIEEE80211
= CFSTR("IEEE80211"); // IEEE 802.11, AirPort
132 const CFStringRef kSCNetworkInterfaceTypeIPSec
= CFSTR("IPSec");
133 const CFStringRef kSCNetworkInterfaceTypeIrDA
= CFSTR("IrDA");
134 const CFStringRef kSCNetworkInterfaceTypeL2TP
= CFSTR("L2TP");
135 const CFStringRef kSCNetworkInterfaceTypeModem
= CFSTR("Modem");
136 const CFStringRef kSCNetworkInterfaceTypePPP
= CFSTR("PPP");
137 const CFStringRef kSCNetworkInterfaceTypePPTP
= CFSTR("PPTP");
138 const CFStringRef kSCNetworkInterfaceTypeSerial
= CFSTR("Serial");
139 #if !TARGET_OS_IPHONE
140 const CFStringRef kSCNetworkInterfaceTypeVLAN
= CFSTR("VLAN");
141 #endif // !TARGET_OS_IPHONE
142 const CFStringRef kSCNetworkInterfaceTypeWWAN
= CFSTR("WWAN");
144 const CFStringRef kSCNetworkInterfaceTypeIPv4
= CFSTR("IPv4");
146 static SCNetworkInterfacePrivate __kSCNetworkInterfaceIPv4
= {
147 INIT_CFRUNTIME_BASE(NULL
, 0, 0x0080), // cfBase
148 NULL
, // interface type
150 NULL
, // localized name
151 NULL
, // localization key
152 NULL
, // localization arg1
153 NULL
, // localization arg2
154 NULL
, // [layered] interface
158 NULL
, // entity_device
159 NULL
, // entity_device_unique
161 NULL
, // entity_subtype
162 NULL
, // supported_interface_types
163 NULL
, // supported_protocol_types
165 NULL
, // addressString
167 NULL
, // configurationAction
174 kSortUnknown
, // sort_order
175 #if !TARGET_OS_IPHONE
176 FALSE
, // supportsBond
177 { NULL
, NULL
}, // bond { interfaces, options }
178 FALSE
, // supportsVLAN
179 { NULL
, NULL
, NULL
} // vlan { interface, tag, options }
180 #endif // !TARGET_OS_IPHONE
183 const SCNetworkInterfaceRef kSCNetworkInterfaceIPv4
= (SCNetworkInterfaceRef
)&__kSCNetworkInterfaceIPv4
;
186 #pragma mark SCNetworkInterface configuration details
195 #define doOverIP do6to4|doL2TP|doPPTP|doIPSec
197 #if !TARGET_OS_IPHONE
198 #define doAppleTalk 1<<0
199 #else // !TARGET_OS_IPHONE
200 #define doAppleTalk 0
201 #endif // !TARGET_OS_IPHONE
205 #define doProxies 1<<4
206 #if !TARGET_OS_IPHONE
208 #else // !TARGET_OS_IPHONE
210 #endif // !TARGET_OS_IPHONE
212 static const struct {
213 const CFStringRef
*interface_type
;
214 const CFStringRef
*entity_hardware
;
215 Boolean per_interface_config
;
216 uint32_t supported_interfaces
;
217 const CFStringRef
*ppp_subtype
;
218 uint32_t supported_protocols
;
219 } configurations
[] = {
220 // interface type entity_hardware if config? interface types PPP sub-type interface protocols
221 // ===================================== ================= ========== =============== ======================================= =========================================
222 { &kSCNetworkInterfaceType6to4
, &kSCEntNet6to4
, FALSE
, doNone
, NULL
, doIPv6
},
223 { &kSCNetworkInterfaceTypeBluetooth
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
224 #if !TARGET_OS_IPHONE
225 { &kSCNetworkInterfaceTypeBond
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doAppleTalk
|doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
226 #endif // !TARGET_OS_IPHONE
227 { &kSCNetworkInterfaceTypeEthernet
, &kSCEntNetEthernet
, TRUE
, doPPP
, &kSCValNetInterfaceSubTypePPPoE
, doAppleTalk
|doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
228 { &kSCNetworkInterfaceTypeFireWire
, &kSCEntNetFireWire
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
229 { &kSCNetworkInterfaceTypeIEEE80211
, &kSCEntNetAirPort
, TRUE
, doPPP
, &kSCValNetInterfaceSubTypePPPoE
, doAppleTalk
|doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
230 { &kSCNetworkInterfaceTypeIPSec
, &kSCEntNetIPSec
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
231 { &kSCNetworkInterfaceTypeIrDA
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
232 { &kSCNetworkInterfaceTypeL2TP
, NULL
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypeL2TP
, doNone
},
233 { &kSCNetworkInterfaceTypeModem
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
234 { &kSCNetworkInterfaceTypePPP
, &kSCEntNetPPP
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
235 { &kSCNetworkInterfaceTypePPTP
, NULL
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPTP
, doNone
},
236 { &kSCNetworkInterfaceTypeSerial
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
237 #if !TARGET_OS_IPHONE
238 { &kSCNetworkInterfaceTypeVLAN
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doAppleTalk
|doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
239 #endif // !TARGET_OS_IPHONE
240 { &kSCNetworkInterfaceTypeWWAN
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
241 // ===================================== ================= ========== =============== ======================================= =========================================
242 { &kSCNetworkInterfaceTypeIPv4
, NULL
, FALSE
, doOverIP
, NULL
, doNone
}
246 #define NETWORKINTERFACE_LOCALIZATIONS CFSTR("NetworkInterface")
247 static CFBundleRef bundle
= NULL
;
250 static CFTypeID __kSCNetworkInterfaceTypeID
= _kCFRuntimeNotATypeID
;
253 static const CFRuntimeClass __SCNetworkInterfaceClass
= {
255 "SCNetworkInterface", // className
258 __SCNetworkInterfaceDeallocate
, // dealloc
259 __SCNetworkInterfaceEqual
, // equal
260 __SCNetworkInterfaceHash
, // hash
261 NULL
, // copyFormattingDesc
262 __SCNetworkInterfaceCopyDescription
// copyDebugDesc
266 static pthread_once_t initialized
= PTHREAD_ONCE_INIT
;
267 static pthread_once_t iokit_quiet
= PTHREAD_ONCE_INIT
;
270 static mach_port_t masterPort
= MACH_PORT_NULL
;
274 __SCNetworkInterfaceCopyDescription(CFTypeRef cf
)
276 CFAllocatorRef allocator
= CFGetAllocator(cf
);
277 CFMutableStringRef result
;
278 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
280 result
= CFStringCreateMutable(allocator
, 0);
281 CFStringAppendFormat(result
, NULL
, CFSTR("<SCNetworkInterface %p [%p]> {"), cf
, allocator
);
282 CFStringAppendFormat(result
, NULL
, CFSTR("type = %@"), interfacePrivate
->interface_type
);
283 CFStringAppendFormat(result
, NULL
, CFSTR(", entity_device = %@"), interfacePrivate
->entity_device
);
284 if (interfacePrivate
->entity_device_unique
!= NULL
) {
285 CFStringAppendFormat(result
, NULL
, CFSTR("+%@"), interfacePrivate
->entity_device_unique
);
287 CFStringAppendFormat(result
, NULL
, CFSTR(", entity_type = %@"), interfacePrivate
->entity_type
);
288 if (interfacePrivate
->entity_subtype
!= NULL
) {
289 CFStringAppendFormat(result
, NULL
, CFSTR(" / %@"), interfacePrivate
->entity_subtype
);
291 if (interfacePrivate
->name
!= NULL
) {
292 CFStringAppendFormat(result
, NULL
, CFSTR(", name = %@"), interfacePrivate
->name
);
294 if (interfacePrivate
->localized_name
!= NULL
) {
295 CFStringAppendFormat(result
, NULL
, CFSTR(", name(l) = %@"), interfacePrivate
->localized_name
);
297 if (interfacePrivate
->localized_key
!= NULL
) {
298 CFStringAppendFormat(result
, NULL
, CFSTR(", name(k) = \"%@\""), interfacePrivate
->localized_key
);
299 if (interfacePrivate
->localized_arg1
!= NULL
) {
300 CFStringAppendFormat(result
, NULL
, CFSTR("+\"%@\""), interfacePrivate
->localized_arg1
);
302 if (interfacePrivate
->localized_arg2
!= NULL
) {
303 CFStringAppendFormat(result
, NULL
, CFSTR("+\"%@\""), interfacePrivate
->localized_arg2
);
307 if (interfacePrivate
->address
!= NULL
) {
312 CFStringAppendFormat(result
, NULL
, CFSTR(", address = 0x"));
314 data
= CFDataGetBytePtr(interfacePrivate
->address
);
315 dataLen
= CFDataGetLength(interfacePrivate
->address
);
316 for (i
= 0; i
< dataLen
; i
++) {
317 CFStringAppendFormat(result
, NULL
, CFSTR("%02x"), data
[i
]);
320 CFStringAppendFormat(result
, NULL
, CFSTR(", builtin = %s"), interfacePrivate
->builtin
? "TRUE" : "FALSE");
321 if (interfacePrivate
->modemIsV92
) {
322 CFStringAppendFormat(result
, NULL
, CFSTR(", v.92"));
324 if (interfacePrivate
->location
!= NULL
) {
325 CFStringAppendFormat(result
, NULL
, CFSTR(", location = %@"), interfacePrivate
->location
);
327 if (interfacePrivate
->type
!= NULL
) {
328 CFStringAppendFormat(result
, NULL
, CFSTR(", type = %@"), interfacePrivate
->type
);
330 if (interfacePrivate
->unit
!= NULL
) {
331 CFStringAppendFormat(result
, NULL
, CFSTR(", unit = %@"), interfacePrivate
->unit
);
333 if (interfacePrivate
->path
!= NULL
) {
334 CFStringAppendFormat(result
, NULL
, CFSTR(", path = %@"), interfacePrivate
->path
);
336 if (interfacePrivate
->configurationAction
!= NULL
) {
337 CFStringAppendFormat(result
, NULL
, CFSTR(", action = %@"), interfacePrivate
->configurationAction
);
339 if (interfacePrivate
->overrides
!= NULL
) {
340 CFStringAppendFormat(result
, NULL
, CFSTR(", overrides = %p"), interfacePrivate
->overrides
);
342 CFStringAppendFormat(result
, NULL
, CFSTR(", order = %d"), interfacePrivate
->sort_order
);
343 if (interfacePrivate
->prefs
!= NULL
) {
344 CFStringAppendFormat(result
, NULL
, CFSTR(", prefs = %p"), interfacePrivate
->prefs
);
346 if (interfacePrivate
->serviceID
!= NULL
) {
347 CFStringAppendFormat(result
, NULL
, CFSTR(", service = %@"), interfacePrivate
->serviceID
);
349 if (interfacePrivate
->interface
!= NULL
) {
350 CFStringAppendFormat(result
, NULL
, CFSTR(", interface = %@"), interfacePrivate
->interface
);
352 if (interfacePrivate
->unsaved
!= NULL
) {
353 CFStringAppendFormat(result
, NULL
, CFSTR(", unsaved = %@"), interfacePrivate
->unsaved
);
355 #if !TARGET_OS_IPHONE
356 if (interfacePrivate
->bond
.interfaces
!= NULL
) {
360 n
= CFArrayGetCount(interfacePrivate
->bond
.interfaces
);
361 for (i
= 0; i
< n
; i
++) {
362 SCNetworkInterfaceRef member
;
364 member
= CFArrayGetValueAtIndex(interfacePrivate
->bond
.interfaces
, i
);
365 CFStringAppendFormat(result
, NULL
,
367 (i
== 0) ? ", interfaces = " : ", ",
368 SCNetworkInterfaceGetBSDName(member
));
371 if (interfacePrivate
->bond
.mode
!= NULL
) {
372 CFStringAppendFormat(result
, NULL
, CFSTR(", mode = %@"), interfacePrivate
->bond
.mode
);
374 if (interfacePrivate
->bond
.options
!= NULL
) {
375 CFStringAppendFormat(result
, NULL
, CFSTR(", options = %@"), interfacePrivate
->bond
.options
);
377 if (interfacePrivate
->bond
.mode
!= NULL
) {
378 CFStringAppendFormat(result
, NULL
, CFSTR(", mode = %@"), interfacePrivate
->bond
.mode
);
380 if (interfacePrivate
->vlan
.interface
!= NULL
) {
381 CFStringAppendFormat(result
, NULL
,
382 CFSTR(", interface = %@"),
383 SCNetworkInterfaceGetBSDName(interfacePrivate
->vlan
.interface
));
385 if (interfacePrivate
->vlan
.tag
!= NULL
) {
386 CFStringAppendFormat(result
, NULL
, CFSTR(", tag = %@"), interfacePrivate
->vlan
.tag
);
388 if (interfacePrivate
->vlan
.options
!= NULL
) {
389 CFStringAppendFormat(result
, NULL
, CFSTR(", options = %@"), interfacePrivate
->vlan
.options
);
391 #endif // !TARGET_OS_IPHONE
392 CFStringAppendFormat(result
, NULL
, CFSTR("}"));
399 __SCNetworkInterfaceDeallocate(CFTypeRef cf
)
401 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
403 /* release resources */
405 if (interfacePrivate
->interface
!= NULL
)
406 CFRelease(interfacePrivate
->interface
);
408 if (interfacePrivate
->name
!= NULL
)
409 CFRelease(interfacePrivate
->name
);
411 if (interfacePrivate
->localized_name
!= NULL
)
412 CFRelease(interfacePrivate
->localized_name
);
414 if (interfacePrivate
->localized_arg1
!= NULL
)
415 CFRelease(interfacePrivate
->localized_arg1
);
417 if (interfacePrivate
->localized_arg2
!= NULL
)
418 CFRelease(interfacePrivate
->localized_arg2
);
420 if (interfacePrivate
->prefs
!= NULL
)
421 CFRelease(interfacePrivate
->prefs
);
423 if (interfacePrivate
->serviceID
!= NULL
)
424 CFRelease(interfacePrivate
->serviceID
);
426 if (interfacePrivate
->unsaved
!= NULL
)
427 CFRelease(interfacePrivate
->unsaved
);
429 if (interfacePrivate
->entity_device
!= NULL
)
430 CFRelease(interfacePrivate
->entity_device
);
432 if (interfacePrivate
->entity_device_unique
!= NULL
)
433 CFRelease(interfacePrivate
->entity_device_unique
);
435 if (interfacePrivate
->supported_interface_types
!= NULL
)
436 CFRelease(interfacePrivate
->supported_interface_types
);
438 if (interfacePrivate
->supported_protocol_types
!= NULL
)
439 CFRelease(interfacePrivate
->supported_protocol_types
);
441 if (interfacePrivate
->address
!= NULL
)
442 CFRelease(interfacePrivate
->address
);
444 if (interfacePrivate
->addressString
!= NULL
)
445 CFRelease(interfacePrivate
->addressString
);
447 if (interfacePrivate
->location
!= NULL
)
448 CFRelease(interfacePrivate
->location
);
450 if (interfacePrivate
->path
!= NULL
)
451 CFRelease(interfacePrivate
->path
);
453 if (interfacePrivate
->configurationAction
!= NULL
)
454 CFRelease(interfacePrivate
->configurationAction
);
456 if (interfacePrivate
->overrides
!= NULL
)
457 CFRelease(interfacePrivate
->overrides
);
459 if (interfacePrivate
->type
!= NULL
)
460 CFRelease(interfacePrivate
->type
);
462 if (interfacePrivate
->unit
!= NULL
)
463 CFRelease(interfacePrivate
->unit
);
465 #if !TARGET_OS_IPHONE
466 if (interfacePrivate
->bond
.interfaces
!= NULL
)
467 CFRelease(interfacePrivate
->bond
.interfaces
);
469 if (interfacePrivate
->bond
.mode
!= NULL
)
470 CFRelease(interfacePrivate
->bond
.mode
);
472 if (interfacePrivate
->bond
.options
!= NULL
)
473 CFRelease(interfacePrivate
->bond
.options
);
475 if (interfacePrivate
->vlan
.interface
!= NULL
)
476 CFRelease(interfacePrivate
->vlan
.interface
);
478 if (interfacePrivate
->vlan
.tag
!= NULL
)
479 CFRelease(interfacePrivate
->vlan
.tag
);
481 if (interfacePrivate
->vlan
.options
!= NULL
)
482 CFRelease(interfacePrivate
->vlan
.options
);
483 #endif // !TARGET_OS_IPHONE
490 __SCNetworkInterfaceEqual(CFTypeRef cf1
, CFTypeRef cf2
)
492 SCNetworkInterfacePrivateRef if1
= (SCNetworkInterfacePrivateRef
)cf1
;
493 SCNetworkInterfacePrivateRef if2
= (SCNetworkInterfacePrivateRef
)cf2
;
498 if (!CFEqual(if1
->interface_type
, if2
->interface_type
)) {
499 return FALSE
; // if not the same interface type
502 if (!_SC_CFEqual(if1
->entity_device
, if2
->entity_device
)) {
503 return FALSE
; // if not the same device
506 if ((if1
->entity_device_unique
!= NULL
) && (if2
->entity_device_unique
!= NULL
)) {
507 if (!_SC_CFEqual(if1
->entity_device_unique
, if2
->entity_device_unique
)) {
508 return FALSE
; // if not the same device unique identifier
510 } else if ((if1
->entity_device_unique
!= NULL
) || (if2
->entity_device_unique
!= NULL
)) {
514 name1
= __SCNetworkInterfaceGetNonLocalizedDisplayName((SCNetworkInterfaceRef
)if1
);
515 name2
= __SCNetworkInterfaceGetNonLocalizedDisplayName((SCNetworkInterfaceRef
)if2
);
516 if ((name1
!= NULL
) && (name2
!= NULL
) && !_SC_CFEqual(name1
, name2
)) {
517 return FALSE
; // if same device but not the same display name
521 #if !TARGET_OS_IPHONE
522 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeBond
)) {
523 if (!_SC_CFEqual(if1
->bond
.interfaces
, if2
->bond
.interfaces
)) {
524 return FALSE
; // if not the same interfaces
526 if (!_SC_CFEqual(if1
->bond
.mode
, if2
->bond
.mode
)) {
527 return FALSE
; // if not the same mode
531 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeVLAN
)) {
532 if (!_SC_CFEqual(if1
->vlan
.interface
, if2
->vlan
.interface
)) {
533 return FALSE
; // if not the same physical interface
535 if (!_SC_CFEqual(if1
->vlan
.tag
, if2
->vlan
.tag
)) {
536 return FALSE
; // if not the same tag
539 #endif // !TARGET_OS_IPHONE
541 if (!_SC_CFEqual(if1
->interface
, if2
->interface
)) {
542 return FALSE
; // if not the same layering
550 __SCNetworkInterfaceHash(CFTypeRef cf
)
553 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
555 if (interfacePrivate
->entity_device
!= NULL
) {
556 if (interfacePrivate
->entity_device_unique
== NULL
) {
557 hash
= CFHash(interfacePrivate
->entity_device
);
561 str
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@+%@"),
562 interfacePrivate
->entity_device
,
563 interfacePrivate
->entity_device_unique
);
574 __SCNetworkInterfaceInitialize(void)
579 __kSCNetworkInterfaceTypeID
= _CFRuntimeRegisterClass(&__SCNetworkInterfaceClass
);
581 // initialize __kSCNetworkInterfaceIPv4
582 _CFRuntimeSetInstanceTypeID(&__kSCNetworkInterfaceIPv4
, __kSCNetworkInterfaceTypeID
);
583 __kSCNetworkInterfaceIPv4
.interface_type
= kSCNetworkInterfaceTypeIPv4
;
584 __kSCNetworkInterfaceIPv4
.localized_key
= CFSTR("ipv4");
586 // get CFBundleRef for SystemConfiguration.framework
587 bundle
= _SC_CFBundleGet();
589 // get mach port used to communication with IOKit
590 kr
= IOMasterPort(MACH_PORT_NULL
, &masterPort
);
591 if (kr
!= KERN_SUCCESS
) {
592 SCLog(TRUE
, LOG_DEBUG
,
593 CFSTR("__SCNetworkInterfaceInitialize(), could not get IOMasterPort, kr = 0x%x"),
602 SCNetworkInterfacePrivateRef
603 __SCNetworkInterfaceCreatePrivate(CFAllocatorRef allocator
,
604 SCNetworkInterfaceRef interface
,
605 SCPreferencesRef prefs
,
606 CFStringRef serviceID
,
609 SCNetworkInterfacePrivateRef interfacePrivate
;
612 /* initialize runtime */
613 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
615 /* allocate target */
616 size
= sizeof(SCNetworkInterfacePrivate
) - sizeof(CFRuntimeBase
);
617 interfacePrivate
= (SCNetworkInterfacePrivateRef
)_CFRuntimeCreateInstance(allocator
,
618 __kSCNetworkInterfaceTypeID
,
621 if (interfacePrivate
== NULL
) {
625 interfacePrivate
->interface_type
= NULL
;
626 interfacePrivate
->name
= NULL
;
627 interfacePrivate
->localized_name
= NULL
;
628 interfacePrivate
->localized_key
= NULL
;
629 interfacePrivate
->localized_arg1
= NULL
;
630 interfacePrivate
->localized_arg2
= NULL
;
631 interfacePrivate
->interface
= (interface
!= NULL
) ? CFRetain(interface
) : NULL
;
632 interfacePrivate
->prefs
= (prefs
!= NULL
) ? CFRetain(prefs
) : NULL
;
633 interfacePrivate
->serviceID
= (serviceID
!= NULL
) ? CFRetain(serviceID
) : NULL
;
634 interfacePrivate
->unsaved
= NULL
;
635 interfacePrivate
->entity_device
= NULL
;
636 interfacePrivate
->entity_device_unique
= NULL
;
637 interfacePrivate
->entity_type
= NULL
;
638 interfacePrivate
->entity_subtype
= NULL
;
639 interfacePrivate
->supported_interface_types
= NULL
;
640 interfacePrivate
->supported_protocol_types
= NULL
;
641 interfacePrivate
->address
= NULL
;
642 interfacePrivate
->addressString
= NULL
;
643 interfacePrivate
->builtin
= FALSE
;
644 interfacePrivate
->configurationAction
= NULL
;
645 interfacePrivate
->path
= (path
!= NULL
) ? CFStringCreateWithCString(NULL
, path
, kCFStringEncodingUTF8
)
647 interfacePrivate
->location
= NULL
;
648 interfacePrivate
->overrides
= NULL
;
649 interfacePrivate
->modemIsV92
= FALSE
;
650 interfacePrivate
->type
= NULL
;
651 interfacePrivate
->unit
= NULL
;
652 interfacePrivate
->sort_order
= kSortUnknown
;
653 #if !TARGET_OS_IPHONE
654 interfacePrivate
->supportsBond
= FALSE
;
655 interfacePrivate
->bond
.interfaces
= NULL
;
656 interfacePrivate
->bond
.mode
= NULL
;
657 interfacePrivate
->bond
.options
= NULL
;
658 interfacePrivate
->supportsVLAN
= FALSE
;
659 interfacePrivate
->vlan
.interface
= NULL
;
660 interfacePrivate
->vlan
.tag
= NULL
;
661 interfacePrivate
->vlan
.options
= NULL
;
662 #endif // !TARGET_OS_IPHONE
664 return interfacePrivate
;
668 #if !TARGET_OS_IPHONE
671 __SCNetworkInterfaceSupportsVLAN(CFStringRef bsd_if
)
675 struct if_msghdr
* ifm
;
676 char * if_name
= NULL
;
677 unsigned int if_index
;
679 Boolean vlanOK
= FALSE
;
681 // get the interface index
682 if_name
= _SC_cfstring_to_cstring(bsd_if
, NULL
, 0, kCFStringEncodingASCII
);
683 if (if_name
== NULL
) {
684 return FALSE
; // if conversion error
686 if_index
= if_nametoindex(if_name
);
688 goto done
; // if unknown interface
691 // get information for the specified interface
696 mib
[4] = NET_RT_IFLIST
;
697 mib
[5] = if_index
; /* ask for exactly one interface */
699 if (sysctl(mib
, 6, NULL
, &buf_len
, NULL
, 0) == -1) {
700 SCLog(TRUE
, LOG_ERR
, CFSTR("sysctl() size failed: %s"), strerror(errno
));
703 buf
= CFAllocatorAllocate(NULL
, buf_len
, 0);
704 if (sysctl(mib
, 6, buf
, &buf_len
, NULL
, 0) == -1) {
705 SCLog(TRUE
, LOG_ERR
, CFSTR("sysctl() failed: %s"), strerror(errno
));
709 // check the link type and hwassist flags
710 ifm
= (struct if_msghdr
*)buf
;
711 switch (ifm
->ifm_type
) {
713 #if defined(IF_HWASSIST_VLAN_TAGGING) && defined(IF_HWASSIST_VLAN_MTU)
714 struct if_data
*if_data
= &ifm
->ifm_data
;
716 if (if_data
->ifi_hwassist
& (IF_HWASSIST_VLAN_TAGGING
| IF_HWASSIST_VLAN_MTU
)) {
726 if (if_name
!= NULL
) CFAllocatorDeallocate(NULL
, if_name
);
727 if (buf
!= NULL
) CFAllocatorDeallocate(NULL
, buf
);
734 SCNetworkInterfacePrivateRef
735 _SCBondInterfaceCreatePrivate(CFAllocatorRef allocator
,
738 SCNetworkInterfacePrivateRef interfacePrivate
;
740 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
, NULL
);
741 if (interfacePrivate
== NULL
) {
745 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBond
;
746 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
747 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, bond_if
);
748 interfacePrivate
->builtin
= TRUE
;
749 interfacePrivate
->supportsVLAN
= __SCNetworkInterfaceSupportsVLAN(bond_if
);
750 interfacePrivate
->sort_order
= kSortBond
;
752 interfacePrivate
->localized_key
= CFSTR("bond");
753 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
755 interfacePrivate
->bond
.interfaces
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
756 // interfacePrivate->bond.mode = NULL;
757 // interfacePrivate->bond.options = NULL;
759 return interfacePrivate
;
764 SCNetworkInterfacePrivateRef
765 _SCVLANInterfaceCreatePrivate(CFAllocatorRef allocator
,
768 SCNetworkInterfacePrivateRef interfacePrivate
;
770 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
, NULL
);
771 if (interfacePrivate
== NULL
) {
775 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeVLAN
;
776 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
777 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, vlan_if
);
778 interfacePrivate
->builtin
= TRUE
;
779 interfacePrivate
->sort_order
= kSortVLAN
;
781 interfacePrivate
->localized_key
= CFSTR("vlan");
782 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
784 // interfacePrivate->vlan.interface = NULL;
785 // interfacePrivate->vlan.tag = NULL;
786 // interfacePrivate->vlan.options = NULL;
788 return interfacePrivate
;
790 #endif // !TARGET_OS_IPHONE
794 #pragma mark Interface ordering
798 split_path(CFStringRef path
)
800 CFArrayRef components
;
801 CFMutableStringRef nPath
;
803 // turn '@'s into '/'s
804 nPath
= CFStringCreateMutableCopy(NULL
, 0, path
);
805 (void) CFStringFindAndReplace(nPath
,
808 CFRangeMake(0, CFStringGetLength(nPath
)),
811 // split path into components to be compared
812 components
= CFStringCreateArrayBySeparatingStrings(NULL
, nPath
, CFSTR("/"));
820 _SCNetworkInterfaceCompare(const void *val1
, const void *val2
, void *context
)
822 SCNetworkInterfacePrivateRef dev1
= (SCNetworkInterfacePrivateRef
)val1
;
823 SCNetworkInterfacePrivateRef dev2
= (SCNetworkInterfacePrivateRef
)val2
;
824 CFComparisonResult res
= kCFCompareEqualTo
;
826 /* sort by interface type */
827 if (dev1
->sort_order
!= dev2
->sort_order
) {
828 if (dev1
->sort_order
< dev2
->sort_order
) {
829 res
= kCFCompareLessThan
;
831 res
= kCFCompareGreaterThan
;
836 /* built-in interfaces sort first */
837 if (dev1
->builtin
!= dev2
->builtin
) {
839 res
= kCFCompareLessThan
;
841 res
= kCFCompareGreaterThan
;
846 /* ... and then, sort built-in interfaces by "location" */
848 if (dev1
->location
!= dev2
->location
) {
849 if (isA_CFString(dev1
->location
)) {
850 if (isA_CFString(dev2
->location
)) {
851 res
= CFStringCompare(dev1
->location
, dev2
->location
, 0);
853 res
= kCFCompareLessThan
;
856 res
= kCFCompareGreaterThan
;
859 if (res
!= kCFCompareEqualTo
) {
865 /* ... and, then sort by IOPathMatch */
866 if ((dev1
->path
!= NULL
) && (dev2
->path
!= NULL
)) {
867 CFArrayRef elements1
;
868 CFArrayRef elements2
;
874 elements1
= split_path(dev1
->path
);
875 n1
= CFArrayGetCount(elements1
);
877 elements2
= split_path(dev2
->path
);
878 n2
= CFArrayGetCount(elements2
);
880 n
= (n1
<= n2
) ? n1
: n2
;
881 for (i
= 0; i
< n
; i
++) {
890 e1
= CFArrayGetValueAtIndex(elements1
, i
);
891 e2
= CFArrayGetValueAtIndex(elements2
, i
);
893 str
= _SC_cfstring_to_cstring(e1
, NULL
, 0, kCFStringEncodingUTF8
);
895 q1
= strtoq(str
, &end
, 16);
896 isNum
= ((*str
!= '\0') && (*end
== '\0') && (errno
== 0));
897 CFAllocatorDeallocate(NULL
, str
);
900 // if e1 is a valid numeric string
901 str
= _SC_cfstring_to_cstring(e2
, NULL
, 0, kCFStringEncodingUTF8
);
903 q2
= strtoq(str
, &end
, 16);
904 isNum
= ((*str
!= '\0') && (*end
== '\0') && (errno
== 0));
905 CFAllocatorDeallocate(NULL
, str
);
908 // if e2 is also a valid numeric string
911 res
= kCFCompareEqualTo
;
913 } else if (q1
< q2
) {
914 res
= kCFCompareLessThan
;
916 res
= kCFCompareGreaterThan
;
922 res
= CFStringCompare(e1
, e2
, 0);
923 if (res
!= kCFCompareEqualTo
) {
928 if (res
== kCFCompareEqualTo
) {
930 res
= kCFCompareLessThan
;
931 } else if (n1
< n2
) {
932 res
= kCFCompareGreaterThan
;
936 CFRelease(elements1
);
937 CFRelease(elements2
);
939 if (res
!= kCFCompareEqualTo
) {
944 /* ... and, then sort by BSD interface name */
945 if ((dev1
->entity_device
!= NULL
) && (dev2
->entity_device
!= NULL
)) {
946 res
= CFStringCompare(dev1
->entity_device
, dev2
->entity_device
, 0);
947 if (res
!= kCFCompareEqualTo
) {
952 /* ... and lastly, sort by BSD interface unique identifier */
953 if ((dev1
->entity_device_unique
!= NULL
) && (dev2
->entity_device_unique
!= NULL
)) {
954 res
= CFStringCompare(dev1
->entity_device_unique
, dev2
->entity_device_unique
, 0);
955 // if (res != kCFCompareEqualTo) {
965 sort_interfaces(CFMutableArrayRef all_interfaces
)
967 int n
= CFArrayGetCount(all_interfaces
);
973 CFArraySortValues(all_interfaces
, CFRangeMake(0, n
), _SCNetworkInterfaceCompare
, NULL
);
980 __SCNetworkInterfaceOrder(SCNetworkInterfaceRef interface
)
982 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
984 return interfacePrivate
->sort_order
;
989 #pragma mark Interface details
993 IOCopyCFStringValue(CFTypeRef ioVal
)
995 if (isA_CFString(ioVal
)) {
996 return CFStringCreateCopy(NULL
, ioVal
);
999 if (isA_CFData(ioVal
)) {
1000 return CFStringCreateWithCString(NULL
,
1001 (const char *)CFDataGetBytePtr(ioVal
),
1002 kCFStringEncodingUTF8
);
1010 IODictionaryCopyCFStringValue(CFDictionaryRef io_dict
, CFStringRef io_key
)
1014 ioVal
= CFDictionaryGetValue(io_dict
, io_key
);
1015 return IOCopyCFStringValue(ioVal
);
1020 IOStringValueHasPrefix(CFTypeRef ioVal
, CFStringRef prefix
)
1022 Boolean match
= FALSE
;
1023 CFIndex prefixLen
= CFStringGetLength(prefix
);
1024 CFStringRef str
= NULL
;
1026 if (!isA_CFString(ioVal
)) {
1027 if (isA_CFData(ioVal
)) {
1028 str
= CFStringCreateWithCStringNoCopy(NULL
,
1029 (const char *)CFDataGetBytePtr(ioVal
),
1030 kCFStringEncodingUTF8
,
1038 if ((ioVal
!= NULL
) &&
1039 (CFStringGetLength(ioVal
) >= prefixLen
) &&
1040 (CFStringCompareWithOptions(ioVal
,
1042 CFRangeMake(0, prefixLen
),
1043 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
)) {
1047 if (str
!= NULL
) CFRelease(str
);
1052 static const struct {
1053 const CFStringRef name
;
1054 const CFStringRef slot
;
1055 } slot_mappings
[] = {
1057 { CFSTR("A1") , CFSTR("1") },
1058 { CFSTR("B1") , CFSTR("2") },
1059 { CFSTR("C1") , CFSTR("3") },
1061 // Blue&White G3, Yikes G4
1062 { CFSTR("J12"), CFSTR("1") },
1063 { CFSTR("J11"), CFSTR("2") },
1064 { CFSTR("J10"), CFSTR("3") },
1065 { CFSTR("J9"), CFSTR("4") },
1068 { CFSTR("A") , CFSTR("1") },
1069 { CFSTR("B") , CFSTR("2") },
1070 { CFSTR("C") , CFSTR("3") },
1071 { CFSTR("D") , CFSTR("4") },
1073 // Digital Audio G4 (and later models)
1074 { CFSTR("1") , CFSTR("1") },
1075 { CFSTR("2") , CFSTR("2") },
1076 { CFSTR("3") , CFSTR("3") },
1077 { CFSTR("4") , CFSTR("4") },
1078 { CFSTR("5") , CFSTR("5") }
1083 pci_slot(io_registry_entry_t interface
, CFTypeRef
*pci_slot_name
)
1086 io_registry_entry_t parent
;
1087 CFMutableStringRef slot
;
1088 CFTypeRef slot_name
;
1091 if (pci_slot_name
!= NULL
) *pci_slot_name
= NULL
;
1093 slot_name
= IORegistryEntryCreateCFProperty(interface
, CFSTR("AAPL,slot-name"), NULL
, 0);
1094 if (slot_name
!= NULL
) {
1097 slot
= CFStringCreateMutable(NULL
, 0);
1098 if (isA_CFString(slot_name
)) {
1099 if (pci_slot_name
!= NULL
) *pci_slot_name
= CFStringCreateCopy(NULL
, slot_name
);
1100 CFStringAppend(slot
, slot_name
);
1101 } else if (isA_CFData(slot_name
)) {
1102 if (pci_slot_name
!= NULL
) *pci_slot_name
= CFDataCreateCopy(NULL
, slot_name
);
1103 CFStringAppendCString(slot
,
1104 (const char *)CFDataGetBytePtr(slot_name
),
1105 kCFStringEncodingUTF8
);
1108 if (CFStringGetLength(slot
) > 5) {
1109 (void) CFStringFindAndReplace(slot
,
1113 kCFCompareCaseInsensitive
|kCFCompareAnchored
);
1116 for (i
= 0; i
< sizeof(slot_mappings
)/sizeof(slot_mappings
[0]); i
++) {
1117 if (CFStringCompare(slot
,
1118 slot_mappings
[i
].name
,
1119 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
1121 slot
= (CFMutableStringRef
)CFRetain(slot_mappings
[i
].slot
);
1126 CFRelease(slot_name
);
1129 kr
= IORegistryEntryGetParentEntry(interface
, kIOServicePlane
, &parent
);
1131 case kIOReturnSuccess
: {
1132 CFTypeRef parent_pci_slot_name
= NULL
;
1133 CFStringRef parent_slot
;
1135 parent_slot
= pci_slot(parent
, &parent_pci_slot_name
);
1136 if (parent_slot
!= NULL
) {
1137 if (slot
!= NULL
) CFRelease(slot
);
1138 slot
= (CFMutableStringRef
)parent_slot
;
1140 if (pci_slot_name
!= NULL
) {
1141 if (*pci_slot_name
!= NULL
) CFRelease(*pci_slot_name
);
1142 *pci_slot_name
= parent_pci_slot_name
;
1144 CFRelease(parent_pci_slot_name
);
1148 IOObjectRelease(parent
);
1151 case kIOReturnNoDevice
:
1152 // if we have hit the root node
1155 SCLog(TRUE
, LOG_DEBUG
, CFSTR("pci_slot IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr
);
1163 static CFComparisonResult
1164 compare_bsdNames(const void *val1
, const void *val2
, void *context
)
1166 CFStringRef bsd1
= (CFStringRef
)val1
;
1167 CFStringRef bsd2
= (CFStringRef
)val2
;
1169 return CFStringCompare(bsd1
, bsd2
, 0);
1174 pci_port(CFTypeRef slot_name
, CFStringRef bsdName
)
1177 CFStringRef port_name
= NULL
;
1178 CFMutableArrayRef port_names
;
1181 CFStringRef match_keys
[2];
1182 CFTypeRef match_vals
[2];
1183 CFDictionaryRef match_dict
;
1184 CFDictionaryRef matching
;
1185 io_registry_entry_t slot
;
1186 io_iterator_t slot_iterator
= MACH_PORT_NULL
;
1188 match_keys
[0] = CFSTR("AAPL,slot-name");
1189 match_vals
[0] = slot_name
;
1191 match_dict
= CFDictionaryCreate(NULL
,
1192 (const void **)match_keys
,
1193 (const void **)match_vals
,
1195 &kCFTypeDictionaryKeyCallBacks
,
1196 &kCFTypeDictionaryValueCallBacks
);
1198 match_keys
[0] = CFSTR(kIOProviderClassKey
);
1199 match_vals
[0] = CFSTR("IOPCIDevice");
1201 match_keys
[1] = CFSTR(kIOPropertyMatchKey
);
1202 match_vals
[1] = match_dict
;
1204 // note: the "matching" dictionary will be consumed by the following
1205 matching
= CFDictionaryCreate(NULL
,
1206 (const void **)match_keys
,
1207 (const void **)match_vals
,
1208 sizeof(match_keys
)/sizeof(match_keys
[0]),
1209 &kCFTypeDictionaryKeyCallBacks
,
1210 &kCFTypeDictionaryValueCallBacks
);
1211 CFRelease(match_dict
);
1213 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &slot_iterator
);
1214 if (kr
!= kIOReturnSuccess
) {
1215 SCLog(TRUE
, LOG_DEBUG
, CFSTR("pci_port IOServiceGetMatchingServices() failed, kr = 0x%x"), kr
);
1216 return MACH_PORT_NULL
;
1219 port_names
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1221 while ((slot
= IOIteratorNext(slot_iterator
)) != MACH_PORT_NULL
) {
1222 io_registry_entry_t child
;
1223 io_iterator_t child_iterator
= MACH_PORT_NULL
;
1225 kr
= IORegistryEntryCreateIterator(slot
,
1227 kIORegistryIterateRecursively
,
1229 if (kr
!= kIOReturnSuccess
) {
1230 SCLog(TRUE
, LOG_DEBUG
, CFSTR("pci_port IORegistryEntryCreateIterator() failed, kr = 0x%x"), kr
);
1231 CFRelease(port_names
);
1232 return MACH_PORT_NULL
;
1235 while ((child
= IOIteratorNext(child_iterator
)) != MACH_PORT_NULL
) {
1236 if (IOObjectConformsTo(child
, kIONetworkInterfaceClass
)) {
1237 CFStringRef if_bsdName
;
1239 if_bsdName
= IORegistryEntryCreateCFProperty(child
,
1240 CFSTR(kIOBSDNameKey
),
1243 if (if_bsdName
!= NULL
) {
1244 CFArrayAppendValue(port_names
, if_bsdName
);
1245 CFRelease(if_bsdName
);
1248 IOObjectRelease(child
);
1250 IOObjectRelease(child_iterator
);
1251 IOObjectRelease(slot
);
1253 IOObjectRelease(slot_iterator
);
1255 n
= CFArrayGetCount(port_names
);
1257 CFArraySortValues(port_names
, CFRangeMake(0, n
), compare_bsdNames
, NULL
);
1258 n
= CFArrayGetFirstIndexOfValue(port_names
, CFRangeMake(0, n
), bsdName
);
1259 if (n
!= kCFNotFound
) {
1260 port_name
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%d"), n
+ 1);
1264 CFRelease(port_names
);
1270 pci_slot_info(io_registry_entry_t interface
, CFStringRef
*slot_name
, CFStringRef
*port_name
)
1272 CFStringRef bsd_name
;
1274 CFTypeRef pci_slot_name
;
1279 bsd_name
= IORegistryEntryCreateCFProperty(interface
, CFSTR(kIOBSDNameKey
), NULL
, 0);
1280 if (bsd_name
== NULL
) {
1284 *slot_name
= pci_slot(interface
, &pci_slot_name
);
1285 if (*slot_name
!= NULL
) {
1286 if (pci_slot_name
!= NULL
) {
1287 *port_name
= pci_port(pci_slot_name
, bsd_name
);
1288 CFRelease(pci_slot_name
);
1293 CFRelease(bsd_name
);
1299 isBuiltin(io_registry_entry_t interface
)
1303 slot
= pci_slot(interface
, NULL
);
1305 // interfaces which have a "slot" are not built-in
1315 isBluetoothBuiltin(Boolean
*haveController
)
1317 Boolean builtin
= FALSE
;
1318 io_object_t hciController
;
1319 io_iterator_t iter
= MACH_PORT_NULL
;
1322 kr
= IOServiceGetMatchingServices(masterPort
,
1323 IOServiceMatching("IOBluetoothHCIController"),
1325 if ((kr
!= kIOReturnSuccess
) || (iter
== MACH_PORT_NULL
)) {
1326 if (kr
!= kIOReturnSuccess
) {
1327 SCLog(TRUE
, LOG_DEBUG
, CFSTR("isBluetoothBuiltin IOServiceGetMatchingServices() failed, kr = 0x%x"), kr
);
1329 *haveController
= FALSE
;
1332 *haveController
= TRUE
;
1334 hciController
= IOIteratorNext(iter
);
1335 IOObjectRelease(iter
);
1336 if(hciController
!= MACH_PORT_NULL
) {
1337 CFNumberRef idVendor
;
1339 idVendor
= IORegistryEntryCreateCFProperty(hciController
, CFSTR(kUSBVendorID
), NULL
, 0);
1340 if (idVendor
!= NULL
) {
1343 if (isA_CFNumber(idVendor
) &&
1344 CFNumberGetValue(idVendor
, kCFNumberIntType
, &idVendorVal
) &&
1345 (idVendorVal
== kIOUSBVendorIDAppleComputer
)) {
1349 CFRelease(idVendor
);
1352 IOObjectRelease(hciController
);
1360 #pragma mark Interface enumeration
1363 typedef Boolean (*processInterface
)(SCNetworkInterfacePrivateRef interfacePrivate
,
1364 io_registry_entry_t interface
,
1365 CFDictionaryRef interface_dict
,
1366 io_registry_entry_t controller
,
1367 CFDictionaryRef controller_dict
,
1368 io_registry_entry_t bus
,
1369 CFDictionaryRef bus_dict
);
1373 processNetworkInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1374 io_registry_entry_t interface
,
1375 CFDictionaryRef interface_dict
,
1376 io_registry_entry_t controller
,
1377 CFDictionaryRef controller_dict
,
1378 io_registry_entry_t bus
,
1379 CFDictionaryRef bus_dict
)
1389 num
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceType
));
1390 if (isA_CFNumber(num
) &&
1391 CFNumberGetValue(num
, kCFNumberIntType
, &ift
)) {
1392 interfacePrivate
->type
= CFRetain(num
);
1394 SCLog(TRUE
, LOG_DEBUG
, CFSTR("processNetworkInterface() failed, no interface type"));
1402 if ((IOObjectConformsTo(controller
, "IO80211Controller")) ||
1403 (IOObjectConformsTo(controller
, "AirPortPCI" )) ||
1404 (IOObjectConformsTo(controller
, "AirPortDriver" ))) {
1405 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
1406 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1407 interfacePrivate
->sort_order
= kSortAirPort
;
1408 } else if (IOObjectConformsTo(controller
, "IOBluetoothBNEPDriver")) {
1409 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1410 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1411 interfacePrivate
->sort_order
= kSortBluetoothPAN
;
1413 str
= IODictionaryCopyCFStringValue(bus_dict
, CFSTR("name"));
1414 if ((str
!= NULL
) && CFEqual(str
, CFSTR("radio"))) {
1415 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
; // ??
1416 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1417 interfacePrivate
->sort_order
= kSortOtherWireless
;
1419 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1420 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1421 interfacePrivate
->sort_order
= kSortEthernet
;
1423 #if !TARGET_OS_IPHONE
1424 // BOND support only enabled for ethernet devices
1425 interfacePrivate
->supportsBond
= TRUE
;
1426 #endif // !TARGET_OS_IPHONE
1429 if (str
!= NULL
) CFRelease(str
);
1432 // check if WWAN Ethernet
1433 if (IOObjectConformsTo(controller
, "AppleUSBEthernetHost")) {
1434 interfacePrivate
->sort_order
= kSortTethered
;
1435 } else if (IOObjectConformsTo(controller
, "AppleUSBCDCECMData")) {
1436 interfacePrivate
->sort_order
= kSortWWANEthernet
;
1440 val
= isA_CFBoolean(CFDictionaryGetValue(interface_dict
, CFSTR(kIOBuiltin
)));
1442 val
= isA_CFBoolean(CFDictionaryGetValue(interface_dict
, CFSTR(kIOPrimaryInterface
)));
1445 interfacePrivate
->builtin
= CFBooleanGetValue(val
);
1447 interfacePrivate
->builtin
= isBuiltin(interface
);
1450 if (!interfacePrivate
->builtin
&&
1451 CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
)) {
1452 // always treat AirPort interfaces as built-in
1453 interfacePrivate
->builtin
= TRUE
;
1457 interfacePrivate
->location
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOLocation
));
1459 #if !TARGET_OS_IPHONE
1461 num
= CFDictionaryGetValue(controller_dict
, CFSTR(kIOFeatures
));
1462 if (isA_CFNumber(num
) &&
1463 CFNumberGetValue(num
, kCFNumberIntType
, & iVal
)) {
1464 if (iVal
& (kIONetworkFeatureHardwareVlan
| kIONetworkFeatureSoftwareVlan
)) {
1465 interfacePrivate
->supportsVLAN
= TRUE
;
1468 #endif // !TARGET_OS_IPHONE
1471 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
)) {
1472 interfacePrivate
->localized_key
= CFSTR("airport");
1473 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN
) {
1474 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan");
1475 } else if (interfacePrivate
->sort_order
== kSortOtherWireless
) {
1476 interfacePrivate
->localized_key
= CFSTR("wireless");
1477 interfacePrivate
->localized_arg1
= CFRetain(CFSTR("")); // ??
1478 } else if (interfacePrivate
->builtin
) {
1479 if ((interfacePrivate
->location
== NULL
) ||
1480 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1481 interfacePrivate
->localized_key
= CFSTR("ether");
1483 interfacePrivate
->localized_key
= CFSTR("multiether");
1484 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->location
);
1487 CFStringRef provider
;
1489 // check provider class
1490 provider
= IORegistryEntrySearchCFProperty(interface
,
1492 CFSTR(kIOProviderClassKey
),
1494 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1495 if (provider
!= NULL
) {
1496 if (CFEqual(provider
, CFSTR("IOPCIDevice"))) {
1497 CFStringRef port_name
;
1498 CFStringRef slot_name
;
1500 if (pci_slot_info(interface
, &slot_name
, &port_name
)) {
1501 if (port_name
== NULL
) {
1502 interfacePrivate
->localized_key
= CFSTR("pci-ether");
1503 interfacePrivate
->localized_arg1
= slot_name
;
1505 interfacePrivate
->localized_key
= CFSTR("pci-multiether");
1506 interfacePrivate
->localized_arg1
= slot_name
;
1507 interfacePrivate
->localized_arg2
= port_name
;
1510 } else if (CFEqual(provider
, CFSTR("IOUSBDevice")) ||
1511 CFEqual(provider
, CFSTR("IOUSBInterface"))) {
1512 // check if a "Product Name" has been provided
1513 val
= IORegistryEntrySearchCFProperty(interface
,
1515 CFSTR(kIOPropertyProductNameKey
),
1517 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1519 // check if a "USB Product Name" has been provided
1520 val
= IORegistryEntrySearchCFProperty(interface
,
1522 CFSTR(kUSBProductString
),
1524 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1527 CFStringRef productName
;
1529 productName
= IOCopyCFStringValue(val
);
1532 if (productName
!= NULL
) {
1533 if (CFStringGetLength(productName
) > 0) {
1534 // if we have a [somewhat reasonable?] product name
1535 if (interfacePrivate
->name
!= NULL
) {
1536 CFRelease(interfacePrivate
->name
);
1538 interfacePrivate
->name
= CFRetain(productName
);
1539 if (interfacePrivate
->localized_name
!= NULL
) {
1540 CFRelease(interfacePrivate
->localized_name
);
1542 interfacePrivate
->localized_name
= copy_interface_string(bundle
, productName
, TRUE
);
1545 CFRelease(productName
);
1548 interfacePrivate
->localized_key
= CFSTR("usb-ether");
1549 interfacePrivate
->localized_arg1
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOBSDNameKey
));
1552 CFRelease(provider
);
1555 if (interfacePrivate
->localized_key
== NULL
) {
1556 // if no provider, not a PCI device, or no slot information
1557 interfacePrivate
->localized_key
= CFSTR("generic-ether");
1558 interfacePrivate
->localized_arg1
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOBSDNameKey
));
1565 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeFireWire
;
1568 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeFireWire
;
1571 interfacePrivate
->builtin
= isBuiltin(interface
);
1574 interfacePrivate
->sort_order
= kSortFireWire
;
1577 if (interfacePrivate
->builtin
) {
1578 interfacePrivate
->localized_key
= CFSTR("firewire");
1580 CFStringRef slot_name
;
1582 slot_name
= pci_slot(interface
, NULL
);
1583 if (slot_name
!= NULL
) {
1584 interfacePrivate
->localized_key
= CFSTR("pci-firewire");
1585 interfacePrivate
->localized_arg1
= slot_name
;
1591 SCLog(TRUE
, LOG_DEBUG
, CFSTR("processNetworkInterface() failed, unknown interface type = %d"), ift
);
1596 interfacePrivate
->entity_device
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOBSDNameKey
));
1598 // Hardware (MAC) address
1599 data
= CFDictionaryGetValue(controller_dict
, CFSTR(kIOMACAddress
));
1600 if (isA_CFData(data
)) {
1601 interfacePrivate
->address
= CFRetain(data
);
1605 num
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceUnit
));
1606 if (isA_CFNumber(num
) &&
1607 CFNumberGetValue(num
, kCFNumberIntType
, & iVal
)) {
1608 interfacePrivate
->unit
= CFRetain(num
);
1616 set_connection_script(SCNetworkInterfacePrivateRef interfacePrivate
, CFStringRef script
)
1618 CFDictionaryRef dict
;
1619 CFMutableDictionaryRef newDict
;
1621 if (interfacePrivate
->overrides
== NULL
) {
1622 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
1624 &kCFTypeDictionaryKeyCallBacks
,
1625 &kCFTypeDictionaryValueCallBacks
);
1628 dict
= CFDictionaryGetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
1630 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
1632 newDict
= CFDictionaryCreateMutable(NULL
,
1634 &kCFTypeDictionaryKeyCallBacks
,
1635 &kCFTypeDictionaryValueCallBacks
);
1637 if (script
!= NULL
) {
1638 CFDictionarySetValue(newDict
, kSCPropNetModemConnectionScript
, script
);
1640 CFDictionaryRemoveValue(newDict
, kSCPropNetModemConnectionScript
);
1642 if (CFDictionaryGetCount(newDict
) > 0) {
1643 CFDictionarySetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
, newDict
);
1645 CFDictionaryRemoveValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
1649 if (CFDictionaryGetCount(interfacePrivate
->overrides
) == 0) {
1650 CFRelease(interfacePrivate
->overrides
);
1651 interfacePrivate
->overrides
= NULL
;
1658 is_valid_connection_script(CFStringRef script
)
1660 char ccl
[MAXPATHLEN
];
1661 char path
[MAXPATHLEN
];
1662 NSSearchPathEnumerationState state
;
1664 (void) _SC_cfstring_to_cstring(script
,
1667 kCFStringEncodingUTF8
);
1669 state
= NSStartSearchPathEnumeration(NSLibraryDirectory
,
1670 NSLocalDomainMask
|NSSystemDomainMask
);
1671 while ((state
= NSGetNextSearchPathEnumeration(state
, path
))) {
1673 struct stat statBuf
;
1675 if (ccl
[0] == '/') {
1676 path
[0] = '\0'; // if modemCCL is a full path
1678 strlcat(path
, "/Modem Scripts/", sizeof(path
));
1680 strlcat(path
, ccl
, sizeof(path
));
1682 if (stat(path
, &statBuf
) != 0) {
1683 if (errno
== ENOENT
) {
1687 SCLog(TRUE
, LOG_DEBUG
,
1688 CFSTR("processSerialInterface stat() failed: %s"),
1692 if (S_ISREG(statBuf
.st_mode
)) {
1693 // if we have a valid CCL script
1697 #define BUNDLE_EXT ".ccl"
1698 #define BUNDLE_EXT_LEN sizeof(BUNDLE_EXT) - 1
1703 if ((n
<= BUNDLE_EXT_LEN
) ||
1704 (strstr(&path
[n
- BUNDLE_EXT_LEN
], BUNDLE_EXT
) == NULL
)) {
1705 strlcat(path
, BUNDLE_EXT
, sizeof(path
));
1706 if (stat(path
, &statBuf
) != 0) {
1707 if (errno
== ENOENT
) {
1711 SCLog(TRUE
, LOG_DEBUG
,
1712 CFSTR("processSerialInterface stat() failed: %s"),
1717 if (S_ISDIR(statBuf
.st_mode
)) {
1718 // if we have a valid CCL bundle
1728 processSerialInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1729 io_registry_entry_t interface
,
1730 CFDictionaryRef interface_dict
,
1731 io_registry_entry_t controller
,
1732 CFDictionaryRef controller_dict
,
1733 io_registry_entry_t bus
,
1734 CFDictionaryRef bus_dict
)
1736 CFStringRef base
= NULL
;
1738 Boolean isModem
= FALSE
;
1739 Boolean isWWAN
= FALSE
;
1740 CFStringRef modemCCL
= NULL
;
1745 val
= IORegistryEntrySearchCFProperty(interface
,
1747 CFSTR("HiddenPort"),
1749 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1752 return FALSE
; // if this interface should not be exposed
1755 // check if initializing
1756 val
= IORegistryEntrySearchCFProperty(interface
,
1758 CFSTR("Initializing"),
1760 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1762 Boolean initializing
;
1764 initializing
= isA_CFBoolean(val
) && CFBooleanGetValue(val
);
1767 return FALSE
; // if this interface is still initializing
1772 val
= IORegistryEntrySearchCFProperty(interface
,
1776 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1778 isWWAN
= isA_CFBoolean(val
) && CFBooleanGetValue(val
);
1783 interfacePrivate
->entity_device
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOTTYDeviceKey
));
1784 if (interfacePrivate
->entity_device
== NULL
) {
1788 base
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOTTYBaseNameKey
));
1790 base
= CFRetain(interfacePrivate
->entity_device
);
1796 * Exclude ports named "irda" because otherwise the IrDA ports on the
1797 * original iMac (rev's A through D) show up as serial ports. Given
1798 * that only the rev A actually had an IrDA port, and Mac OS X doesn't
1799 * even support it, these ports definitely shouldn't be listed.
1801 if (CFStringCompare(base
,
1803 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
1807 if (IOStringValueHasPrefix(base
, CFSTR("bluetooth"))) {
1808 Boolean haveController
= FALSE
;
1811 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBluetooth
;
1812 interfacePrivate
->sort_order
= kSortBluetooth
;
1813 interfacePrivate
->builtin
= isBluetoothBuiltin(&haveController
);
1814 if (!haveController
) {
1815 // if device with no controller present
1818 } else if (IOStringValueHasPrefix(base
, CFSTR("irda-ircomm"))) {
1820 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIrDA
;
1821 interfacePrivate
->sort_order
= kSortIrDA
;
1822 } else if (isWWAN
) {
1824 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeWWAN
;
1825 interfacePrivate
->sort_order
= kSortWWAN
;
1828 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeModem
;
1829 interfacePrivate
->sort_order
= kSortModem
;
1832 val
= IORegistryEntrySearchCFProperty(interface
,
1834 CFSTR(kIODeviceSupportsHoldKey
),
1836 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1840 if (isA_CFNumber(val
) &&
1841 CFNumberGetValue(val
, kCFNumberSInt32Type
, &v92
)) {
1842 interfacePrivate
->modemIsV92
= (v92
== 1);
1849 interfacePrivate
->entity_type
= kSCEntNetModem
;
1851 // Entity (Hardware)
1852 ift
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOSerialBSDTypeKey
));
1853 if (!isA_CFString(ift
)) {
1857 if (CFEqual(ift
, CFSTR(kIOSerialBSDModemType
))) {
1861 if (CFEqual(base
, CFSTR("modem"))) {
1862 interfacePrivate
->builtin
= TRUE
;
1863 interfacePrivate
->sort_order
= kSortInternalModem
;
1864 } else if (CFEqual(base
, CFSTR("usbmodem"))) {
1865 interfacePrivate
->sort_order
= kSortUSBModem
;
1867 } else if (CFEqual(ift
, CFSTR(kIOSerialBSDRS232Type
))) {
1869 interfacePrivate
->sort_order
= kSortSerialPort
;
1874 // configuration template overrides
1875 val
= IORegistryEntrySearchCFProperty(interface
,
1877 CFSTR("DevicePPPOverrides"),
1879 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1881 if (isA_CFDictionary(val
)) {
1882 if (interfacePrivate
->overrides
== NULL
) {
1883 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
1885 &kCFTypeDictionaryKeyCallBacks
,
1886 &kCFTypeDictionaryValueCallBacks
);
1888 CFDictionarySetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypePPP
, val
);
1893 val
= IORegistryEntrySearchCFProperty(interface
,
1895 CFSTR("DeviceModemOverrides"),
1897 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1899 if (isA_CFDictionary(val
)) {
1900 CFStringRef uniqueID
;
1902 if (interfacePrivate
->overrides
== NULL
) {
1903 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
1905 &kCFTypeDictionaryKeyCallBacks
,
1906 &kCFTypeDictionaryValueCallBacks
);
1908 CFDictionarySetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
, val
);
1910 modemCCL
= CFDictionaryGetValue(val
, kSCPropNetModemConnectionScript
);
1911 modemCCL
= isA_CFString(modemCCL
);
1913 uniqueID
= CFDictionaryGetValue(val
, CFSTR("UniqueIdentifier"));
1914 uniqueID
= isA_CFString(uniqueID
);
1915 if (uniqueID
!= NULL
) {
1916 // retain the device's base name and the unique id
1917 CFRelease(interfacePrivate
->entity_device
);
1918 interfacePrivate
->entity_device
= CFRetain(base
);
1919 interfacePrivate
->entity_device_unique
= CFStringCreateCopy(NULL
, uniqueID
);
1925 // if not part of the DeviceModemOverrides, look harder for the modem CCL
1926 if (modemCCL
== NULL
) {
1927 val
= IORegistryEntrySearchCFProperty(interface
,
1931 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1933 modemCCL
= IOCopyCFStringValue(val
);
1934 if (modemCCL
!= NULL
) {
1935 set_connection_script(interfacePrivate
, modemCCL
);
1936 CFRelease(modemCCL
);
1944 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIrDA
)) {
1945 interfacePrivate
->localized_key
= CFSTR("irda");
1946 } else if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBluetooth
)) {
1947 interfacePrivate
->localized_key
= CFSTR("bluetooth");
1949 CFStringRef localized
= NULL
;
1950 CFStringRef name
= NULL
;
1951 CFMutableStringRef port
;
1953 port
= CFStringCreateMutableCopy(NULL
, 0, base
);
1954 CFStringLowercase(port
, NULL
);
1957 CFStringAppend(port
, CFSTR("-port"));
1960 // set non-localized name
1961 if (bundle
!= NULL
) {
1962 name
= copy_interface_string(bundle
, port
, FALSE
);
1965 if (!CFEqual(port
, name
)) {
1966 // if [English] localization available
1967 interfacePrivate
->name
= name
;
1969 // if no [English] localization available, use TTY base name
1971 interfacePrivate
->name
= CFStringCreateCopy(NULL
, base
);
1974 interfacePrivate
->name
= CFStringCreateCopy(NULL
, base
);
1977 // set localized name
1978 if (bundle
!= NULL
) {
1979 localized
= copy_interface_string(bundle
, port
, TRUE
);
1981 if (localized
!= NULL
) {
1982 if (!CFEqual(port
, localized
)) {
1983 // if localization available
1984 interfacePrivate
->localized_name
= localized
;
1986 // if no localization available, use TTY base name
1987 CFRelease(localized
);
1988 interfacePrivate
->localized_name
= CFStringCreateCopy(NULL
, base
);
1991 interfacePrivate
->localized_name
= CFStringCreateCopy(NULL
, base
);
1994 if (!isModem
|| !CFEqual(base
, CFSTR("modem"))) {
1995 CFStringRef productName
;
1997 // check if a "Product Name" has been provided
1998 val
= IORegistryEntrySearchCFProperty(interface
,
2000 CFSTR(kIOPropertyProductNameKey
),
2002 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2004 // check if a "USB Product Name" has been provided
2005 val
= IORegistryEntrySearchCFProperty(interface
,
2007 CFSTR(kUSBProductString
),
2009 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2012 productName
= IOCopyCFStringValue(val
);
2015 if (productName
!= NULL
) {
2016 if (CFStringGetLength(productName
) > 0) {
2017 // if we have a [somewhat reasonable?] product name
2018 if (interfacePrivate
->name
!= NULL
) {
2019 CFRelease(interfacePrivate
->name
);
2021 interfacePrivate
->name
= CFRetain(productName
);
2022 if (interfacePrivate
->localized_name
!= NULL
) {
2023 CFRelease(interfacePrivate
->localized_name
);
2025 interfacePrivate
->localized_name
= copy_interface_string(bundle
, productName
, TRUE
);
2027 // if not provided, also check if the product name
2028 // matches a CCL script
2029 if ((modemCCL
== NULL
) &&
2030 is_valid_connection_script(productName
)) {
2031 set_connection_script(interfacePrivate
, productName
);
2035 CFRelease(productName
);
2047 if (!ok
&& (interfacePrivate
->entity_device
!= NULL
)) {
2048 CFRelease(interfacePrivate
->entity_device
);
2049 interfacePrivate
->entity_device
= NULL
;
2051 if (base
!= NULL
) CFRelease(base
);
2057 static SCNetworkInterfaceRef
2058 createInterface(io_registry_entry_t interface
, processInterface func
)
2060 io_registry_entry_t bus
= MACH_PORT_NULL
;
2061 CFMutableDictionaryRef bus_dict
= NULL
;
2062 io_registry_entry_t controller
= MACH_PORT_NULL
;
2063 CFMutableDictionaryRef controller_dict
= NULL
;
2064 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
2065 CFMutableDictionaryRef interface_dict
= NULL
;
2069 kr
= IORegistryEntryGetPath(interface
, kIOServicePlane
, path
);
2070 if (kr
!= kIOReturnSuccess
) {
2071 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryGetPath() failed, kr = 0x%x"), kr
);
2075 kr
= IORegistryEntryCreateCFProperties(interface
, &interface_dict
, NULL
, kNilOptions
);
2076 if (kr
!= kIOReturnSuccess
) {
2077 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryCreateCFProperties() failed, kr = 0x%x"), kr
);
2081 /* get the controller node */
2082 kr
= IORegistryEntryGetParentEntry(interface
, kIOServicePlane
, &controller
);
2083 if (kr
!= KERN_SUCCESS
) {
2084 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr
);
2088 /* get the dictionary associated with the node */
2089 kr
= IORegistryEntryCreateCFProperties(controller
, &controller_dict
, NULL
, kNilOptions
);
2090 if (kr
!= KERN_SUCCESS
) {
2091 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryCreateCFProperties() failed, kr = 0x%x"), kr
);
2095 /* get the bus node */
2096 kr
= IORegistryEntryGetParentEntry(controller
, kIOServicePlane
, &bus
);
2097 if (kr
!= KERN_SUCCESS
) {
2098 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr
);
2102 /* get the dictionary associated with the node */
2103 kr
= IORegistryEntryCreateCFProperties(bus
, &bus_dict
, NULL
, kNilOptions
);
2104 if (kr
!= KERN_SUCCESS
) {
2105 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryCreateCFProperties() failed, kr = 0x%x"), kr
);
2109 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
, path
);
2111 if ((*func
)(interfacePrivate
, interface
, interface_dict
, controller
, controller_dict
, bus
, bus_dict
)) {
2114 /* check user-notification / auto-configuration preferences */
2115 val
= IORegistryEntrySearchCFProperty(interface
,
2117 kSCNetworkInterfaceConfigurationActionKey
,
2119 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2121 if (isA_CFString(val
)) {
2122 interfacePrivate
->configurationAction
= CFRetain(val
);
2127 CFRelease(interfacePrivate
);
2128 interfacePrivate
= NULL
;
2133 if (interface_dict
!= NULL
) CFRelease(interface_dict
);
2135 if (controller
!= MACH_PORT_NULL
) IOObjectRelease(controller
);
2136 if (controller_dict
!= NULL
) CFRelease(controller_dict
);
2138 if (bus
!= MACH_PORT_NULL
) IOObjectRelease(bus
);
2139 if (bus_dict
!= NULL
) CFRelease(bus_dict
);
2141 return (SCNetworkInterfaceRef
)interfacePrivate
;
2146 findMatchingInterfaces(CFDictionaryRef matching
, processInterface func
)
2148 CFMutableArrayRef interfaces
;
2149 io_registry_entry_t interface
;
2151 io_iterator_t iterator
= MACH_PORT_NULL
;
2153 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &iterator
);
2154 if (kr
!= kIOReturnSuccess
) {
2155 SCLog(TRUE
, LOG_DEBUG
, CFSTR("findMatchingInterfaces IOServiceGetMatchingServices() failed, kr = 0x%x"), kr
);
2159 interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2161 while ((interface
= IOIteratorNext(iterator
)) != MACH_PORT_NULL
) {
2162 SCNetworkInterfaceRef match
;
2164 match
= createInterface(interface
, func
);
2165 if (match
!= NULL
) {
2166 CFArrayAppendValue(interfaces
, match
);
2170 IOObjectRelease(interface
);
2173 IOObjectRelease(iterator
);
2180 #pragma mark helper functions
2184 findConfiguration(CFStringRef interface_type
)
2188 for (i
= 0; i
< sizeof(configurations
)/sizeof(configurations
[0]); i
++) {
2189 if (CFEqual(interface_type
, *configurations
[i
].interface_type
)) {
2200 __SCNetworkInterfaceGetDefaultConfigurationType(SCNetworkInterfaceRef interface
)
2202 CFIndex interfaceIndex
;
2203 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2205 if (interfacePrivate
->serviceID
== NULL
) {
2206 // if not associated with a service (yet)
2207 _SCErrorSet(kSCStatusInvalidArgument
);
2211 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2212 if (interfaceIndex
== kCFNotFound
) {
2213 // unknown interface type, use per-service configuration preferences
2214 return interfacePrivate
->interface_type
; // entity
2217 if (configurations
[interfaceIndex
].entity_hardware
!= NULL
) {
2218 // if configuration information can be associated with this interface type
2219 return *configurations
[interfaceIndex
].entity_hardware
;
2222 _SCErrorSet(kSCStatusInvalidArgument
);
2229 __SCNetworkInterfaceIsValidExtendedConfigurationType(SCNetworkInterfaceRef interface
,
2230 CFStringRef extendedType
,
2231 Boolean requirePerInterface
)
2233 CFStringRef defaultType
;
2234 CFIndex extendedIndex
;
2235 CFIndex interfaceIndex
;
2236 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2237 Boolean isL2TP
= FALSE
;
2240 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
2241 if (defaultType
== NULL
) {
2245 if (CFEqual(extendedType
, defaultType
)) {
2246 // extended and default configuration types cannot conflict
2250 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2251 if (interfaceIndex
== kCFNotFound
) {
2252 // configuration information for unknown interface type's
2253 // are stored along with the service and we don't allow
2254 // per-service extended configurations
2258 if (CFEqual(extendedType
, kSCEntNetIPSec
)) {
2259 CFStringRef interfaceType
;
2261 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
2262 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
2263 SCNetworkInterfaceRef child
;
2265 child
= SCNetworkInterfaceGetInterface(interface
);
2266 if (child
!= NULL
) {
2267 interfaceType
= SCNetworkInterfaceGetInterfaceType(child
);
2268 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
2275 if (requirePerInterface
&&
2276 !configurations
[interfaceIndex
].per_interface_config
&&
2278 // we don't allow per-service extended configurations (except
2279 // that we do allow IPSec as an extended type for PPP->L2TP)
2283 extendedIndex
= findConfiguration(extendedType
);
2284 if ((extendedIndex
!= kCFNotFound
) && !isL2TP
) {
2285 // extended type cannot match a known interface type (except
2286 // that we do allow IPSec as an extended type for PPP->L2TP)
2292 * Do we match specific/known extended configuration types (e.g. EAPOL)
2293 * and ensure that any non-standard extended configuration types be of
2294 * the form com.myCompany.myType?
2303 _SCErrorSet(kSCStatusInvalidArgument
);
2310 CFStringRef defaultType
;
2311 CFMutableArrayRef types
;
2312 } extendedConfiguration
, *extendedConfigurationRef
;
2316 __addExtendedConfigurationType(const void *key
, const void *value
, void *context
)
2318 CFStringRef extendedType
= (CFStringRef
)key
;
2319 extendedConfigurationRef myContextRef
= (extendedConfigurationRef
)context
;
2321 if (CFEqual(extendedType
, myContextRef
->defaultType
)) {
2322 // do not include the default configuration type
2326 if (CFArrayContainsValue(myContextRef
->types
,
2327 CFRangeMake(0, CFArrayGetCount(myContextRef
->types
)),
2329 // if extendedType already has already been added
2333 CFArrayAppendValue(myContextRef
->types
, extendedType
);
2340 extendedConfigurationTypes(SCNetworkInterfaceRef interface
)
2343 CFIndex interfaceIndex
;
2344 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2345 extendedConfiguration myContext
;
2346 SCNetworkServiceRef service
;
2350 myContext
.defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
2351 if (myContext
.defaultType
== NULL
) {
2352 myContext
.types
= NULL
;
2356 myContext
.types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2358 if (interfacePrivate
->serviceID
== NULL
) {
2359 // if not associated with a service (yet)
2363 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2364 if (interfaceIndex
== kCFNotFound
) {
2365 // we don't allow per-service extended configurations
2369 if (!configurations
[interfaceIndex
].per_interface_config
) {
2370 // known interface type but we still don't allow
2371 // per-service extended configurations
2375 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
2376 interfacePrivate
->prefs
,
2377 interfacePrivate
->serviceID
,
2380 sets
= SCNetworkSetCopyAll(interfacePrivate
->prefs
);
2381 n
= (sets
!= NULL
) ? CFArrayGetCount(sets
) : 0;
2383 for (i
= 0; i
< n
; i
++) {
2384 CFDictionaryRef configs
;
2387 CFArrayRef services
;
2388 SCNetworkSetRef set
;
2390 set
= CFArrayGetValueAtIndex(sets
, i
);
2391 services
= SCNetworkSetCopyServices(set
);
2392 found
= CFArrayContainsValue(services
,
2393 CFRangeMake(0, CFArrayGetCount(services
)),
2395 CFRelease(services
);
2401 // add stored extended configuration types
2402 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
2403 SCNetworkSetGetSetID(set
), // set
2404 interfacePrivate
->entity_device
, // service
2406 configs
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
2408 if (isA_CFDictionary(configs
)) {
2409 CFDictionaryApplyFunction(configs
,
2410 __addExtendedConfigurationType
,
2414 // add not-yet-stored extended configuration types
2415 if (interfacePrivate
->unsaved
!= NULL
) {
2416 CFDictionaryApplyFunction(interfacePrivate
->unsaved
,
2417 __addExtendedConfigurationType
,
2425 if (sets
!= NULL
) CFRelease(sets
);
2429 return myContext
.types
;
2434 copyConfigurationPaths(SCNetworkInterfacePrivateRef interfacePrivate
,
2435 CFStringRef extendedType
)
2437 CFMutableArrayRef array
;
2439 CFIndex interfaceIndex
;
2442 SCNetworkServiceRef service
;
2445 array
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2447 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2448 if (interfaceIndex
== kCFNotFound
) {
2449 // unknown interface type, use per-service configuration preferences
2450 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
2451 interfacePrivate
->serviceID
, // service
2452 extendedType
); // entity
2453 CFArrayAppendValue(array
, path
);
2458 if (!configurations
[interfaceIndex
].per_interface_config
) {
2459 // known interface type, per-service configuration preferences
2460 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
2461 interfacePrivate
->serviceID
, // service
2462 extendedType
); // entity
2463 CFArrayAppendValue(array
, path
);
2468 // known interface type, per-interface configuration preferences
2470 // 1. look for all sets which contain the associated service
2471 // 2. add a per-set path for the interface configuration for
2474 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
2475 interfacePrivate
->prefs
,
2476 interfacePrivate
->serviceID
,
2477 (SCNetworkInterfaceRef
)interfacePrivate
);
2479 sets
= SCNetworkSetCopyAll(interfacePrivate
->prefs
);
2480 n
= (sets
!= NULL
) ? CFArrayGetCount(sets
) : 0;
2482 for (i
= 0; i
< n
; i
++) {
2483 CFArrayRef services
;
2484 SCNetworkSetRef set
;
2486 set
= CFArrayGetValueAtIndex(sets
, i
);
2487 services
= SCNetworkSetCopyServices(set
);
2488 if (CFArrayContainsValue(services
,
2489 CFRangeMake(0, CFArrayGetCount(services
)),
2491 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
2492 SCNetworkSetGetSetID(set
), // set
2493 interfacePrivate
->entity_device
, // service
2494 extendedType
); // entity
2495 CFArrayAppendValue(array
, path
);
2498 CFRelease(services
);
2501 if (CFArrayGetCount(array
) == 0) {
2507 if (sets
!= NULL
) CFRelease(sets
);
2513 #pragma mark SCNetworkInterface <--> preferences entity
2518 __SCNetworkInterfaceCopyInterfaceEntity(SCNetworkInterfaceRef interface
)
2520 CFMutableDictionaryRef entity
;
2521 CFIndex interfaceIndex
;
2522 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2524 entity
= CFDictionaryCreateMutable(NULL
,
2526 &kCFTypeDictionaryKeyCallBacks
,
2527 &kCFTypeDictionaryValueCallBacks
);
2528 if (interfacePrivate
->entity_type
!= NULL
) {
2529 CFDictionarySetValue(entity
,
2530 kSCPropNetInterfaceType
,
2531 interfacePrivate
->entity_type
);
2533 if (interfacePrivate
->entity_subtype
!= NULL
) {
2534 CFDictionarySetValue(entity
,
2535 kSCPropNetInterfaceSubType
,
2536 interfacePrivate
->entity_subtype
);
2538 if (interfacePrivate
->entity_device
!= NULL
) {
2539 CFDictionarySetValue(entity
,
2540 kSCPropNetInterfaceDeviceName
,
2541 interfacePrivate
->entity_device
);
2543 if (interfacePrivate
->entity_device_unique
!= NULL
) {
2544 CFDictionarySetValue(entity
,
2545 CFSTR("DeviceUniqueIdentifier"),
2546 interfacePrivate
->entity_device_unique
);
2549 // match the "hardware" with the lowest layer
2551 SCNetworkInterfaceRef nextInterface
;
2553 nextInterface
= SCNetworkInterfaceGetInterface(interface
);
2554 if (nextInterface
== NULL
) {
2558 interface
= nextInterface
;
2560 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2562 if (CFEqual(interface
, kSCNetworkInterfaceIPv4
)) {
2566 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2567 if (interfaceIndex
!= kCFNotFound
) {
2568 if (configurations
[interfaceIndex
].entity_hardware
!= NULL
) {
2569 CFDictionarySetValue(entity
,
2570 kSCPropNetInterfaceHardware
,
2571 *configurations
[interfaceIndex
].entity_hardware
);
2574 CFDictionarySetValue(entity
,
2575 kSCPropNetInterfaceHardware
,
2576 interfacePrivate
->interface_type
);
2579 // add the localized display name (which will only be used when/if the
2580 // interface is removed from the system)
2581 CFDictionarySetValue(entity
,
2582 kSCPropUserDefinedName
,
2583 SCNetworkInterfaceGetLocalizedDisplayName(interface
));
2585 // note that this is a V.92 capable modem
2586 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeModem
) &&
2587 interfacePrivate
->modemIsV92
) {
2591 num
= CFNumberCreate(NULL
, kCFNumberIntType
, &one
);
2592 CFDictionarySetValue(entity
,
2593 kSCPropNetInterfaceSupportsModemOnHold
,
2602 #if !TARGET_OS_IPHONE
2603 static SCNetworkInterfaceRef
2604 findInterface(CFArrayRef interfaces
, CFStringRef match_if
)
2609 n
= CFArrayGetCount(interfaces
);
2610 for (i
= 0; i
< n
; i
++) {
2611 SCNetworkInterfaceRef interface
= CFArrayGetValueAtIndex(interfaces
, i
);
2612 CFStringRef interfaceName
;
2614 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
2615 if ((interfaceName
!= NULL
) && CFEqual(interfaceName
, match_if
)) {
2616 CFRetain(interface
);
2625 static SCNetworkInterfaceRef
2626 findBondInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
2629 SCNetworkInterfaceRef interface
= NULL
;
2631 if (prefs
== NULL
) {
2635 // check if the interface is an Ethernet Bond
2636 bonds
= SCBondInterfaceCopyAll(prefs
);
2637 if (bonds
!= NULL
) {
2638 interface
= findInterface(bonds
, ifDevice
);
2644 static SCNetworkInterfaceRef
2645 findVLANInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
2647 SCNetworkInterfaceRef interface
= NULL
;
2650 if (prefs
== NULL
) {
2654 // check if the interface is a VLAN
2655 vlans
= SCVLANInterfaceCopyAll(prefs
);
2656 if (vlans
!= NULL
) {
2657 interface
= findInterface(vlans
, ifDevice
);
2662 #endif // !TARGET_OS_IPHONE
2665 SCNetworkInterfaceRef
2666 _SCNetworkInterfaceCreateWithBSDName(CFAllocatorRef allocator
,
2667 CFStringRef bsdName
,
2670 CFMutableDictionaryRef entity
;
2671 SCNetworkInterfaceRef interface
;
2673 entity
= CFDictionaryCreateMutable(NULL
,
2675 &kCFTypeDictionaryKeyCallBacks
,
2676 &kCFTypeDictionaryValueCallBacks
);
2677 CFDictionarySetValue(entity
, kSCPropNetInterfaceDeviceName
, bsdName
);
2678 #if !TARGET_OS_IPHONE
2679 if ((flags
& kIncludeBondInterfaces
) == 0) {
2680 CFDictionarySetValue(entity
, CFSTR("_NO_BOND_INTERFACES_"), kCFBooleanTrue
);
2682 if ((flags
& kIncludeVLANInterfaces
) == 0) {
2683 CFDictionarySetValue(entity
, CFSTR("_NO_VLAN_INTERFACES_"), kCFBooleanTrue
);
2685 #endif // !TARGET_OS_IPHONE
2686 interface
= _SCNetworkInterfaceCreateWithEntity(NULL
, entity
, NULL
);
2694 __SCNetworkInterfaceSetService(SCNetworkInterfaceRef interface
,
2695 SCNetworkServiceRef service
)
2697 SCNetworkInterfacePrivateRef interfacePrivate
;
2698 SCNetworkServicePrivateRef servicePrivate
;
2700 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2701 if (interfacePrivate
->prefs
!= NULL
) {
2702 CFRelease(interfacePrivate
->prefs
);
2703 interfacePrivate
->prefs
= NULL
;
2705 if (interfacePrivate
->serviceID
!= NULL
) {
2706 CFRelease(interfacePrivate
->serviceID
);
2707 interfacePrivate
->serviceID
= NULL
;
2710 servicePrivate
= (SCNetworkServicePrivateRef
)service
;
2711 if (servicePrivate
->prefs
!= NULL
) {
2712 interfacePrivate
->prefs
= CFRetain(servicePrivate
->prefs
);
2714 if (servicePrivate
->serviceID
!= NULL
) {
2715 interfacePrivate
->serviceID
= CFRetain(servicePrivate
->serviceID
);
2723 _SCNetworkInterfaceMatchesName(CFStringRef name
, CFStringRef key
)
2728 if (bundle
== NULL
) {
2733 if (!isA_CFString(name
)) {
2734 // if no interface "name"
2738 // check non-localized name for a match
2739 str
= copy_interface_string(bundle
, key
, FALSE
);
2741 match
= CFEqual(name
, str
);
2748 // check localized name for a match
2749 str
= copy_interface_string(bundle
, key
, TRUE
);
2751 match
= CFEqual(name
, str
);
2762 SCNetworkInterfaceRef
2763 _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef allocator
,
2764 CFDictionaryRef interface_entity
,
2765 SCNetworkServiceRef service
)
2767 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
2768 CFStringRef ifDevice
;
2769 CFStringRef ifName
= NULL
;
2770 CFStringRef ifSubType
;
2772 CFStringRef ifUnique
;
2773 CFArrayRef matching_interfaces
= NULL
;
2775 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
2776 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
2778 ifType
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceType
);
2779 if (ifType
== NULL
) {
2781 * The interface "Type" was not specified. We'll make an
2782 * assumption that this is an "Ethernet" interface. If a
2783 * real interface exists with the provided interface name
2784 * then the actual type will be set accordingly. If not, we'll
2785 * end up crafting an "Ethernet" SCNetworkInterface which
2786 * will keep the rest of the configuration APIs happy.
2788 ifType
= kSCValNetInterfaceTypeEthernet
;
2791 if (!isA_CFString(ifType
)) {
2795 ifSubType
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceSubType
);
2796 if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
2797 if (!isA_CFString(ifSubType
)) {
2802 ifDevice
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceDeviceName
);
2803 ifUnique
= CFDictionaryGetValue(interface_entity
, CFSTR("DeviceUniqueIdentifier"));
2805 if (CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
) ||
2806 CFEqual(ifType
, kSCValNetInterfaceTypeFireWire
) ||
2807 (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) && CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPoE
))) {
2808 char bsdName
[IFNAMSIZ
+ 1];
2809 CFMutableDictionaryRef matching
;
2811 if (!isA_CFString(ifDevice
)) {
2815 if (_SC_cfstring_to_cstring(ifDevice
, bsdName
, sizeof(bsdName
), kCFStringEncodingASCII
) == NULL
) {
2819 matching
= IOBSDNameMatching(masterPort
, 0, bsdName
);
2820 if (matching
== NULL
) {
2824 // note: the "matching" dictionary will be consumed by the following
2825 matching_interfaces
= findMatchingInterfaces(matching
, processNetworkInterface
);
2827 } else if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
2828 if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPSerial
)) {
2829 CFDictionaryRef matching
;
2830 CFStringRef match_keys
[2];
2831 CFStringRef match_vals
[2];
2833 if (!isA_CFString(ifDevice
)) {
2837 match_keys
[0] = CFSTR(kIOProviderClassKey
);
2838 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
2840 match_keys
[1] = CFSTR(kIOTTYBaseNameKey
);
2841 match_vals
[1] = ifDevice
;
2843 matching
= CFDictionaryCreate(NULL
,
2844 (const void **)match_keys
,
2845 (const void **)match_vals
,
2846 sizeof(match_keys
)/sizeof(match_keys
[0]),
2847 &kCFTypeDictionaryKeyCallBacks
,
2848 &kCFTypeDictionaryValueCallBacks
);
2850 // note: the "matching" dictionary will be consumed by the following
2851 matching_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
);
2853 if (ifUnique
== NULL
) {
2855 Boolean useDeviceName
= TRUE
;
2857 n
= (matching_interfaces
!= NULL
) ? CFArrayGetCount(matching_interfaces
) : 0;
2861 for (i
= 0; i
< n
; i
++) {
2862 SCNetworkInterfacePrivateRef scanPrivate
;
2864 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
2865 if (scanPrivate
->entity_device_unique
!= NULL
) {
2866 useDeviceName
= FALSE
;
2872 if (useDeviceName
) {
2873 if (matching_interfaces
!= NULL
) {
2874 CFRelease(matching_interfaces
);
2877 match_keys
[1] = CFSTR(kIOTTYDeviceKey
);
2878 matching
= CFDictionaryCreate(NULL
,
2879 (const void **)match_keys
,
2880 (const void **)match_vals
,
2881 sizeof(match_keys
)/sizeof(match_keys
[0]),
2882 &kCFTypeDictionaryKeyCallBacks
,
2883 &kCFTypeDictionaryValueCallBacks
);
2885 // note: the "matching" dictionary will be consumed by the following
2886 matching_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
);
2889 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypeL2TP
)) {
2890 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
2891 kSCNetworkInterfaceTypeL2TP
);
2892 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPTP
)) {
2893 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
2894 kSCNetworkInterfaceTypePPTP
);
2896 // XXX do we allow non-Apple variants of PPP??? XXX
2897 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
2900 } else if (CFEqual(ifType
, kSCValNetInterfaceType6to4
)) {
2901 if (!isA_CFString(ifDevice
)) {
2905 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
2906 kSCNetworkInterfaceType6to4
);
2907 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeIPSec
)) {
2908 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
2909 kSCNetworkInterfaceTypeIPSec
);
2910 } else if ((CFStringFind(ifType
, CFSTR("."), 0).location
!= kCFNotFound
) && (ifDevice
== NULL
)) {
2911 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
2915 if (matching_interfaces
!= NULL
) {
2917 SCPreferencesRef prefs
;
2919 n
= CFArrayGetCount(matching_interfaces
);
2922 interfacePrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, 0);
2923 if (_SC_CFEqual(ifUnique
, interfacePrivate
->entity_device_unique
)) {
2924 // if the unique ID's match
2925 CFRetain(interfacePrivate
);
2929 interfacePrivate
= NULL
;
2932 if (!CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
)) {
2935 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), NULL
);
2936 if (prefs
== NULL
) {
2939 #if !TARGET_OS_IPHONE
2940 if (!CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_VLAN_INTERFACES_"))) {
2941 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findVLANInterface(prefs
, ifDevice
);
2943 if ((interfacePrivate
== NULL
)
2944 && !CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_BOND_INTERFACES_"))) {
2945 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findBondInterface(prefs
, ifDevice
);
2947 #endif // !TARGET_OS_IPHONE
2951 if (ifUnique
!= NULL
) {
2954 // we are looking for an interface with a unique ID
2955 // so let's try to focus our choices
2956 for (i
= 0; i
< n
; i
++) {
2957 SCNetworkInterfacePrivateRef scanPrivate
;
2959 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
2960 if (_SC_CFEqual(ifUnique
, scanPrivate
->entity_device_unique
)) {
2961 if (interfacePrivate
!= NULL
) {
2962 // if we've matched more than one interface
2963 interfacePrivate
= NULL
;
2966 interfacePrivate
= scanPrivate
;
2969 } else if (CFDictionaryGetValueIfPresent(interface_entity
,
2970 kSCPropUserDefinedName
,
2971 (const void **)&ifName
)) {
2974 // we don't have a unique ID but do have an interface
2975 // name. If the matching interfaces do have IDs than
2976 // we can try to focus our choices using the name
2977 for (i
= 0; i
< n
; i
++) {
2978 SCNetworkInterfacePrivateRef scanPrivate
;
2980 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
2981 if (scanPrivate
->entity_device_unique
!= NULL
) {
2982 SCNetworkInterfaceRef scan
= (SCNetworkInterfaceRef
)scanPrivate
;
2983 CFStringRef scanName
;
2985 scanName
= __SCNetworkInterfaceGetNonLocalizedDisplayName(scan
);
2986 if ((scanName
!= NULL
) && !_SC_CFEqual(ifName
, scanName
)) {
2987 continue; // if not the same display name
2991 if (interfacePrivate
!= NULL
) {
2992 // if we've matched more than one interface
2993 interfacePrivate
= NULL
;
2996 interfacePrivate
= scanPrivate
;
2999 if (interfacePrivate
== NULL
) {
3000 SCLog(TRUE
, LOG_ERR
, CFSTR("_SCNetworkInterfaceCreateWithEntity() failed, more than one interface matches %@"), ifDevice
);
3001 interfacePrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, 0);
3003 CFRetain(interfacePrivate
);
3006 CFRelease(matching_interfaces
);
3011 if (interfacePrivate
== NULL
) {
3013 * if device not present on this system
3015 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
, NULL
);
3016 interfacePrivate
->entity_type
= ifType
;
3017 interfacePrivate
->entity_subtype
= ifSubType
;
3018 interfacePrivate
->entity_device
= (ifDevice
!= NULL
) ? CFStringCreateCopy(NULL
, ifDevice
) : NULL
;
3019 interfacePrivate
->entity_device_unique
= (ifUnique
!= NULL
) ? CFStringCreateCopy(NULL
, ifUnique
) : NULL
;
3021 if (CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
)) {
3022 CFStringRef entity_hardware
;
3024 entity_hardware
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceHardware
);
3025 if (isA_CFString((entity_hardware
)) &&
3026 CFEqual(entity_hardware
, kSCEntNetAirPort
)) {
3027 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
3028 interfacePrivate
->sort_order
= kSortAirPort
;
3032 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
3034 name
= CFDictionaryGetValue(interface_entity
, kSCPropUserDefinedName
);
3035 if (_SCNetworkInterfaceMatchesName(name
, CFSTR("iPhone"))) {
3036 interfacePrivate
->sort_order
= kSortTethered
;
3037 } else if (_SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan"))) {
3038 interfacePrivate
->sort_order
= kSortBluetoothPAN
;
3040 interfacePrivate
->sort_order
= kSortEthernet
;
3043 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeFireWire
)) {
3044 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeFireWire
;
3045 interfacePrivate
->sort_order
= kSortFireWire
;
3046 } else if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
3047 if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPoE
)) {
3048 CFStringRef entity_hardware
;
3050 entity_hardware
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceHardware
);
3051 if (isA_CFString((entity_hardware
)) &&
3052 CFEqual(entity_hardware
, kSCEntNetAirPort
)) {
3053 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
3054 interfacePrivate
->sort_order
= kSortAirPort
;
3056 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
3057 interfacePrivate
->sort_order
= kSortEthernet
;
3059 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPSerial
)) {
3060 if (CFStringHasPrefix(ifDevice
, CFSTR("Bluetooth"))) {
3061 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBluetooth
;
3062 interfacePrivate
->sort_order
= kSortBluetooth
;
3063 } else if (CFStringHasPrefix(ifDevice
, CFSTR("irda"))) {
3064 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIrDA
;
3065 interfacePrivate
->sort_order
= kSortIrDA
;
3066 } else if (CFStringHasPrefix(ifDevice
, CFSTR("wwan"))) {
3067 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeWWAN
;
3068 interfacePrivate
->sort_order
= kSortWWAN
;
3070 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeModem
;
3071 interfacePrivate
->sort_order
= kSortModem
;
3075 CFRelease(interfacePrivate
);
3076 interfacePrivate
= (SCNetworkInterfacePrivateRef
)kSCNetworkInterfaceIPv4
;
3077 CFRetain(interfacePrivate
);
3079 } else if (CFStringFind(ifType
, CFSTR("."), 0).location
!= kCFNotFound
) {
3080 // if vendor interface
3081 interfacePrivate
->interface_type
= ifType
;
3083 // if unknown interface
3084 CFRelease(interfacePrivate
);
3085 interfacePrivate
= NULL
;
3089 if ((interfacePrivate
!= NULL
) && (service
!= NULL
)) {
3090 __SCNetworkInterfaceSetService((SCNetworkInterfaceRef
)interfacePrivate
,
3092 #if !TARGET_OS_IPHONE
3093 // set prefs & serviceID to VLANs and Bonds
3094 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBond
)) {
3099 members
= SCBondInterfaceGetMemberInterfaces((SCNetworkInterfaceRef
)interfacePrivate
);
3100 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
3101 for (i
= 0; i
< n
; i
++) {
3102 SCNetworkInterfaceRef member
;
3104 member
= CFArrayGetValueAtIndex(members
, i
);
3105 __SCNetworkInterfaceSetService(member
, service
);
3107 } else if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeVLAN
)) {
3108 SCNetworkInterfaceRef vlan_physical
;
3110 vlan_physical
= SCVLANInterfaceGetPhysicalInterface((SCNetworkInterfaceRef
)interfacePrivate
);
3111 if (vlan_physical
!= NULL
) {
3112 __SCNetworkInterfaceSetService(vlan_physical
, service
);
3115 #endif // !TARGET_OS_IPHONE
3118 if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
3119 SCNetworkInterfaceRef parent
;
3122 parent
= SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef
)interfacePrivate
,
3123 kSCNetworkInterfaceTypePPP
);
3124 CFRelease(interfacePrivate
);
3125 interfacePrivate
= (SCNetworkInterfacePrivateRef
)parent
;
3128 return (SCNetworkInterfaceRef
)interfacePrivate
;
3133 #pragma mark SCNetworkInterface APIs
3138 __SCNetworkInterfaceCopyAll_IONetworkInterface(void)
3140 CFDictionaryRef matching
;
3141 CFArrayRef new_interfaces
;
3143 // get Ethernet, Firewire, and AirPort interfaces
3145 matching
= IOServiceMatching(kIONetworkInterfaceClass
);
3146 new_interfaces
= findMatchingInterfaces(matching
, processNetworkInterface
);
3148 return new_interfaces
;
3154 __SCNetworkInterfaceCopyAll_Modem()
3156 CFDictionaryRef matching
;
3157 CFStringRef match_keys
[2];
3158 CFStringRef match_vals
[2];
3159 CFArrayRef new_interfaces
;
3161 match_keys
[0] = CFSTR(kIOProviderClassKey
);
3162 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
3164 match_keys
[1] = CFSTR(kIOSerialBSDTypeKey
);
3165 match_vals
[1] = CFSTR(kIOSerialBSDModemType
);
3167 matching
= CFDictionaryCreate(NULL
,
3168 (const void **)match_keys
,
3169 (const void **)match_vals
,
3170 sizeof(match_keys
)/sizeof(match_keys
[0]),
3171 &kCFTypeDictionaryKeyCallBacks
,
3172 &kCFTypeDictionaryValueCallBacks
);
3173 new_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
);
3175 return new_interfaces
;
3181 __SCNetworkInterfaceCopyAll_RS232()
3183 CFDictionaryRef matching
;
3184 CFStringRef match_keys
[2];
3185 CFStringRef match_vals
[2];
3186 CFArrayRef new_interfaces
;
3188 match_keys
[0] = CFSTR(kIOProviderClassKey
);
3189 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
3191 match_keys
[1] = CFSTR(kIOSerialBSDTypeKey
);
3192 match_vals
[1] = CFSTR(kIOSerialBSDRS232Type
);
3194 matching
= CFDictionaryCreate(NULL
,
3195 (const void **)match_keys
,
3196 (const void **)match_vals
,
3197 sizeof(match_keys
)/sizeof(match_keys
[0]),
3198 &kCFTypeDictionaryKeyCallBacks
,
3199 &kCFTypeDictionaryValueCallBacks
);
3200 new_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
);
3202 return new_interfaces
;
3207 add_interfaces(CFMutableArrayRef all_interfaces
, CFArrayRef new_interfaces
)
3212 n
= CFArrayGetCount(new_interfaces
);
3213 for (i
= 0; i
< n
; i
++) {
3214 CFStringRef bsdName
;
3215 SCNetworkInterfaceRef interface
;
3217 interface
= CFArrayGetValueAtIndex(new_interfaces
, i
);
3218 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
3219 if (bsdName
!= NULL
) {
3220 CFArrayAppendValue(all_interfaces
, interface
);
3229 __waitForInterfaces()
3234 SCDynamicStoreRef store
;
3236 store
= SCDynamicStoreCreate(NULL
, CFSTR("SCNetworkInterfaceCopyAll"), NULL
, NULL
);
3237 if (store
== NULL
) {
3241 key
= SCDynamicStoreKeyCreate(NULL
, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin
);
3242 keys
= CFArrayCreate(NULL
, (const void **)&key
, 1, &kCFTypeArrayCallBacks
);
3243 ok
= SCDynamicStoreSetNotificationKeys(store
, keys
, NULL
);
3246 SCLog(TRUE
, LOG_ERR
,
3247 CFSTR("SCDynamicStoreSetNotificationKeys() failed: %s"), SCErrorString(SCError()));
3252 CFArrayRef changedKeys
;
3253 CFDictionaryRef dict
;
3254 Boolean quiet
= FALSE
;
3257 dict
= SCDynamicStoreCopyValue(store
, key
);
3259 if (isA_CFDictionary(dict
) &&
3260 (CFDictionaryContainsKey(dict
, CFSTR("*QUIET*")) ||
3261 CFDictionaryContainsKey(dict
, CFSTR("*TIMEOUT*")))) {
3270 ok
= SCDynamicStoreNotifyWait(store
);
3272 SCLog(TRUE
, LOG_ERR
,
3273 CFSTR("SCDynamicStoreNotifyWait() failed: %s"), SCErrorString(SCError()));
3277 changedKeys
= SCDynamicStoreCopyNotifiedKeys(store
);
3278 if (changedKeys
!= NULL
) {
3279 CFRelease(changedKeys
);
3291 CFArrayRef
/* of SCNetworkInterfaceRef's */
3292 SCNetworkInterfaceCopyAll()
3294 CFMutableArrayRef all_interfaces
;
3295 CFArrayRef new_interfaces
;
3296 #if !TARGET_OS_IPHONE
3297 SCPreferencesRef prefs
;
3298 #endif // !TARGET_OS_IPHONE
3300 /* initialize runtime */
3301 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
3303 /* wait for IOKit to quiesce */
3304 pthread_once(&iokit_quiet
, __waitForInterfaces
);
3306 all_interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3308 // get Ethernet, Firewire, and AirPort interfaces
3309 new_interfaces
= __SCNetworkInterfaceCopyAll_IONetworkInterface();
3310 if (new_interfaces
!= NULL
) {
3311 add_interfaces(all_interfaces
, new_interfaces
);
3312 CFRelease(new_interfaces
);
3315 // get Modem interfaces
3316 new_interfaces
= __SCNetworkInterfaceCopyAll_Modem();
3317 if (new_interfaces
!= NULL
) {
3318 add_interfaces(all_interfaces
, new_interfaces
);
3319 CFRelease(new_interfaces
);
3322 // get serial (RS232) interfaces
3323 new_interfaces
= __SCNetworkInterfaceCopyAll_RS232();
3324 if (new_interfaces
!= NULL
) {
3325 add_interfaces(all_interfaces
, new_interfaces
);
3326 CFRelease(new_interfaces
);
3329 #if !TARGET_OS_IPHONE
3330 // get virtual network interfaces (Bond, VLAN)
3331 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterfaceCopyAll"), NULL
);
3332 if (prefs
!= NULL
) {
3333 new_interfaces
= SCBondInterfaceCopyAll(prefs
);
3334 if (new_interfaces
!= NULL
) {
3335 add_interfaces(all_interfaces
, new_interfaces
);
3336 CFRelease(new_interfaces
);
3339 new_interfaces
= SCVLANInterfaceCopyAll(prefs
);
3340 if (new_interfaces
!= NULL
) {
3341 add_interfaces(all_interfaces
, new_interfaces
);
3342 CFRelease(new_interfaces
);
3347 #endif // !TARGET_OS_IPHONE
3349 // all interfaces have been identified, order and return
3350 sort_interfaces(all_interfaces
);
3352 return all_interfaces
;
3356 CFArrayRef
/* of kSCNetworkInterfaceTypeXXX CFStringRef's */
3357 SCNetworkInterfaceGetSupportedInterfaceTypes(SCNetworkInterfaceRef interface
)
3360 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3362 if (!isA_SCNetworkInterface(interface
)) {
3363 _SCErrorSet(kSCStatusInvalidArgument
);
3367 if (interfacePrivate
->supported_interface_types
!= NULL
) {
3371 i
= findConfiguration(interfacePrivate
->interface_type
);
3372 if (i
!= kCFNotFound
) {
3373 if (configurations
[i
].supported_interfaces
!= doNone
) {
3374 interfacePrivate
->supported_interface_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3375 if (configurations
[i
].supported_interfaces
& do6to4
) {
3376 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceType6to4
);
3378 if (configurations
[i
].supported_interfaces
& doL2TP
) {
3379 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeL2TP
);
3381 if (configurations
[i
].supported_interfaces
& doPPP
) {
3382 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypePPP
);
3384 if (configurations
[i
].supported_interfaces
& doPPTP
) {
3385 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypePPTP
);
3387 if (configurations
[i
].supported_interfaces
& doIPSec
) {
3388 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeIPSec
);
3395 return interfacePrivate
->supported_interface_types
;
3399 CFArrayRef
/* of kSCNetworkProtocolTypeXXX CFStringRef's */
3400 SCNetworkInterfaceGetSupportedProtocolTypes(SCNetworkInterfaceRef interface
)
3403 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3405 if (!isA_SCNetworkInterface(interface
)) {
3406 _SCErrorSet(kSCStatusInvalidArgument
);
3410 if (interfacePrivate
->supported_protocol_types
!= NULL
) {
3414 i
= findConfiguration(interfacePrivate
->interface_type
);
3415 if (i
!= kCFNotFound
) {
3416 if (configurations
[i
].supported_protocols
!= doNone
) {
3417 interfacePrivate
->supported_protocol_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3418 #if !TARGET_OS_IPHONE
3419 if (configurations
[i
].supported_protocols
& doAppleTalk
) {
3420 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeAppleTalk
);
3422 #endif // !TARGET_OS_IPHONE
3423 if (configurations
[i
].supported_protocols
& doDNS
) {
3424 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeDNS
);
3426 if (configurations
[i
].supported_protocols
& doIPv4
) {
3427 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeIPv4
);
3429 if (configurations
[i
].supported_protocols
& doIPv6
) {
3430 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeIPv6
);
3432 if (configurations
[i
].supported_protocols
& doProxies
) {
3433 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeProxies
);
3435 #if !TARGET_OS_IPHONE
3436 if (configurations
[i
].supported_protocols
& doSMB
) {
3437 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeSMB
);
3439 #endif // !TARGET_OS_IPHONE
3445 return interfacePrivate
->supported_protocol_types
;
3449 SCNetworkInterfaceRef
3450 SCNetworkInterfaceCreateWithInterface(SCNetworkInterfaceRef child
, CFStringRef interfaceType
)
3452 SCNetworkInterfacePrivateRef childPrivate
= (SCNetworkInterfacePrivateRef
)child
;
3454 SCNetworkInterfacePrivateRef parentPrivate
;
3456 if (!isA_SCNetworkInterface(child
)) {
3457 _SCErrorSet(kSCStatusInvalidArgument
);
3461 if (!isA_CFString(interfaceType
)) {
3462 _SCErrorSet(kSCStatusInvalidArgument
);
3466 childIndex
= findConfiguration(childPrivate
->interface_type
);
3468 parentPrivate
= __SCNetworkInterfaceCreatePrivate(NULL
,
3470 childPrivate
->prefs
,
3471 childPrivate
->serviceID
,
3473 if (parentPrivate
== NULL
) {
3474 _SCErrorSet(kSCStatusFailed
);
3478 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
3479 parentPrivate
->interface_type
= kSCNetworkInterfaceTypePPP
;
3480 parentPrivate
->entity_type
= kSCValNetInterfaceTypePPP
;
3483 if (childIndex
!= kCFNotFound
) {
3484 if (configurations
[childIndex
].ppp_subtype
!= NULL
) {
3485 parentPrivate
->entity_subtype
= *configurations
[childIndex
].ppp_subtype
;
3487 // sorry, the child interface does not support PPP
3491 // if the child's interface type not known, use the child entities "Type"
3492 parentPrivate
->entity_subtype
= childPrivate
->entity_type
;
3495 if (childPrivate
->entity_device
!= NULL
) {
3496 parentPrivate
->entity_device
= CFStringCreateCopy(NULL
, childPrivate
->entity_device
);
3499 if (childPrivate
->entity_device_unique
!= NULL
) {
3500 parentPrivate
->entity_device_unique
= CFStringCreateCopy(NULL
, childPrivate
->entity_device_unique
);
3502 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
3503 if ((childIndex
== kCFNotFound
) ||
3504 ((configurations
[childIndex
].supported_interfaces
& doL2TP
) != doL2TP
)) {
3505 // if the child interface does not support L2TP
3508 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeL2TP
;
3509 parentPrivate
->localized_key
= CFSTR("l2tp");
3510 parentPrivate
->entity_type
= kSCEntNetL2TP
; // interface config goes into "L2TP"
3511 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPTP
)) {
3512 if ((childIndex
== kCFNotFound
) ||
3513 ((configurations
[childIndex
].supported_interfaces
& doPPTP
) != doPPTP
)) {
3514 // if the child interface does not support PPTP
3517 parentPrivate
->interface_type
= kSCNetworkInterfaceTypePPTP
;
3518 parentPrivate
->localized_key
= CFSTR("pptp");
3519 parentPrivate
->entity_type
= kSCEntNetPPTP
; // interface config goes into "PPTP"
3520 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceType6to4
)) {
3521 if ((childIndex
== kCFNotFound
) ||
3522 ((configurations
[childIndex
].supported_interfaces
& do6to4
) != do6to4
)) {
3523 // if the child interface does not support 6to4
3527 parentPrivate
->interface_type
= kSCNetworkInterfaceType6to4
;
3528 parentPrivate
->localized_key
= CFSTR("6to4");
3529 parentPrivate
->entity_type
= kSCValNetInterfaceType6to4
;
3530 parentPrivate
->entity_device
= CFRetain(CFSTR("stf0"));
3531 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
3532 if ((childIndex
== kCFNotFound
) ||
3533 ((configurations
[childIndex
].supported_interfaces
& doIPSec
) != doIPSec
)) {
3534 // if the child interface does not support IPSec
3537 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeIPSec
;
3538 parentPrivate
->localized_key
= CFSTR("ipsec");
3539 parentPrivate
->entity_type
= kSCValNetInterfaceTypeIPSec
;
3540 } else if (CFStringFind(interfaceType
, CFSTR("."), 0).location
!= kCFNotFound
) {
3541 // if custom interface type
3542 parentPrivate
->interface_type
= interfaceType
;
3543 parentPrivate
->entity_type
= interfaceType
; // interface config goes into a
3544 // a dictionary with the same
3545 // name as the interfaceType
3547 // unknown interface type
3551 if (childPrivate
->overrides
!= NULL
) {
3552 parentPrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, childPrivate
->overrides
);
3555 // The following change handles the case where a user has both an Ethernet and
3556 // PPPoE network service. Because a PPPoE service is typically associated with
3557 // an ISP we want it to be sorted higher in the service order.
3558 if ((parentPrivate
->entity_subtype
!= NULL
) &&
3559 (CFEqual(parentPrivate
->entity_subtype
, kSCValNetInterfaceSubTypePPPoE
))) {
3560 if ((childPrivate
->interface_type
!= NULL
) &&
3561 (CFEqual(childPrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
))) {
3562 parentPrivate
->sort_order
= kSortAirportPPP
;
3564 parentPrivate
->sort_order
= kSortEthernetPPP
;
3567 // set sort order of the parent to match the child interface
3568 parentPrivate
->sort_order
= childPrivate
->sort_order
;
3571 return (SCNetworkInterfaceRef
)parentPrivate
;
3575 CFRelease(parentPrivate
);
3576 _SCErrorSet(kSCStatusInvalidArgument
);
3583 __SCNetworkInterfaceGetDefaultConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
)
3585 CFDictionaryRef config
= NULL
;
3586 CFStringRef defaultType
;
3587 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3589 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
3590 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
3592 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
3593 if (defaultType
!= NULL
) {
3597 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
3598 SCNetworkSetGetSetID(set
), // set
3599 interfacePrivate
->entity_device
, // interface
3600 defaultType
); // entity
3602 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
3605 if (config
== NULL
) {
3606 // if the "set" does not have a saved configuration, use
3607 // the [template] "interface" configuration
3608 if (interfacePrivate
->unsaved
!= NULL
) {
3609 config
= CFDictionaryGetValue(interfacePrivate
->unsaved
, defaultType
);
3610 if (config
== (CFDictionaryRef
)kCFNull
) {
3615 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
3626 static CFDictionaryRef
3627 __SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface
,
3628 CFStringRef extendedType
)
3630 CFDictionaryRef config
= NULL
;
3631 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3634 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
3635 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
3637 paths
= copyConfigurationPaths(interfacePrivate
, extendedType
);
3638 if (paths
!= NULL
) {
3641 path
= CFArrayGetValueAtIndex(paths
, 0);
3642 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
3646 if (interfacePrivate
->unsaved
!= NULL
) {
3647 config
= CFDictionaryGetValue(interfacePrivate
->unsaved
, extendedType
);
3648 if (config
== (CFDictionaryRef
)kCFNull
) {
3654 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
3663 SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface
)
3665 CFDictionaryRef config
;
3666 CFStringRef defaultType
;
3668 if (!isA_SCNetworkInterface(interface
)) {
3669 _SCErrorSet(kSCStatusInvalidArgument
);
3673 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
3674 if (defaultType
== NULL
) {
3678 config
= __SCNetworkInterfaceGetConfiguration(interface
, defaultType
);
3679 if (config
== NULL
) {
3680 if (CFEqual(defaultType
, kSCEntNetAirPort
)) {
3681 SCNetworkInterfacePrivateRef interfacePrivate
;
3684 // if AirPort interface, check for a per-service config
3685 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3686 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
3687 interfacePrivate
->serviceID
, // service
3688 kSCEntNetAirPort
); // entity
3689 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
3693 if (config
== NULL
) {
3694 _SCErrorSet(kSCStatusOK
);
3702 SCNetworkInterfaceGetExtendedConfiguration(SCNetworkInterfaceRef interface
,
3703 CFStringRef extendedType
)
3705 CFDictionaryRef config
;
3707 if (!isA_SCNetworkInterface(interface
)) {
3708 _SCErrorSet(kSCStatusInvalidArgument
);
3712 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, TRUE
)) {
3713 _SCErrorSet(kSCStatusInvalidArgument
);
3717 config
= __SCNetworkInterfaceGetConfiguration(interface
, extendedType
);
3718 if (config
== NULL
) {
3719 _SCErrorSet(kSCStatusOK
);
3727 SCNetworkInterfaceGetBSDName(SCNetworkInterfaceRef interface
)
3729 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3731 if (!isA_SCNetworkInterface(interface
)) {
3732 _SCErrorSet(kSCStatusInvalidArgument
);
3736 if ((interfacePrivate
->interface
!= NULL
) &&
3737 (interfacePrivate
->interface
!= kSCNetworkInterfaceIPv4
)) {
3738 _SCErrorSet(kSCStatusOK
);
3742 return interfacePrivate
->entity_device
;
3747 SCNetworkInterfaceGetHardwareAddressString(SCNetworkInterfaceRef interface
)
3749 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3751 if (!isA_SCNetworkInterface(interface
)) {
3752 _SCErrorSet(kSCStatusInvalidArgument
);
3756 if ((interfacePrivate
->address
!= NULL
) &&
3757 (interfacePrivate
->addressString
== NULL
)) {
3761 char mac
[sizeof("xx:xx:xx:xx:xx:xx:xx:xx")];
3764 bp
= (uint8_t *)CFDataGetBytePtr(interfacePrivate
->address
);
3765 n
= CFDataGetLength(interfacePrivate
->address
) * 3;
3767 if (n
> sizeof(mac
)) {
3768 mac_p
= CFAllocatorAllocate(NULL
, 0, n
);
3771 for (cp
= mac_p
; n
> 0; n
-= 3) {
3772 cp
+= snprintf(cp
, n
, "%2.2x:", *bp
++);
3775 interfacePrivate
->addressString
= CFStringCreateWithCString(NULL
, mac_p
, kCFStringEncodingUTF8
);
3776 if (mac_p
!= mac
) CFAllocatorDeallocate(NULL
, mac_p
);
3779 return interfacePrivate
->addressString
;
3783 SCNetworkInterfaceRef
3784 SCNetworkInterfaceGetInterface(SCNetworkInterfaceRef interface
)
3786 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3788 if (!isA_SCNetworkInterface(interface
)) {
3789 _SCErrorSet(kSCStatusInvalidArgument
);
3793 return interfacePrivate
->interface
;
3798 SCNetworkInterfaceGetInterfaceType(SCNetworkInterfaceRef interface
)
3800 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3802 if (!isA_SCNetworkInterface(interface
)) {
3803 _SCErrorSet(kSCStatusInvalidArgument
);
3807 return interfacePrivate
->interface_type
;
3812 copy_interface_string(CFBundleRef bundle
, CFStringRef key
, Boolean localized
)
3814 CFStringRef str
= NULL
;
3817 str
= CFBundleCopyLocalizedString(bundle
,
3820 NETWORKINTERFACE_LOCALIZATIONS
);
3822 str
= _SC_CFBundleCopyNonLocalizedString(bundle
,
3825 NETWORKINTERFACE_LOCALIZATIONS
);
3833 copy_display_name(SCNetworkInterfaceRef interface
, Boolean localized
, Boolean oldLocalization
)
3835 CFMutableStringRef local
;
3838 local
= CFStringCreateMutable(NULL
, 0);
3840 while (interface
!= NULL
) {
3841 Boolean added
= FALSE
;
3842 SCNetworkInterfaceRef child
= NULL
;
3843 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3845 if ((interfacePrivate
->interface
!= NULL
) &&
3846 (interfacePrivate
->interface
!= kSCNetworkInterfaceIPv4
)) {
3847 child
= interfacePrivate
->interface
;
3850 if ((bundle
!= NULL
) && (interfacePrivate
->localized_key
!= NULL
)) {
3852 CFStringRef key
= interfacePrivate
->localized_key
;
3854 if (oldLocalization
) {
3855 key
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("X-%@"),
3856 interfacePrivate
->localized_key
);
3858 fmt
= copy_interface_string(bundle
, key
, localized
);
3860 CFStringAppendFormat(local
,
3863 interfacePrivate
->localized_arg1
,
3864 interfacePrivate
->localized_arg2
);
3868 if (oldLocalization
) {
3874 (interfacePrivate
->prefs
!= NULL
) &&
3875 (interfacePrivate
->serviceID
!= NULL
) &&
3877 CFDictionaryRef entity
;
3880 // check for (and use) the name of the interface when it
3881 // was last available
3882 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,
3883 interfacePrivate
->serviceID
,
3884 kSCEntNetInterface
);
3885 entity
= SCPreferencesPathGetValue(interfacePrivate
->prefs
, path
);
3887 if (isA_CFDictionary(entity
)) {
3890 name
= CFDictionaryGetValue(entity
, kSCPropUserDefinedName
);
3891 if (isA_CFString(name
)) {
3892 CFStringAppend(local
, name
);
3899 // create (non-)localized name based on the interface type
3900 CFStringAppend(local
, interfacePrivate
->interface_type
);
3902 // ... and, if this is a leaf node, the interface device
3903 if ((interfacePrivate
->entity_device
!= NULL
) && (child
== NULL
)) {
3904 CFStringAppendFormat(local
, NULL
, CFSTR(" (%@)"), interfacePrivate
->entity_device
);
3908 if (child
!= NULL
) {
3909 // if this interface is layered over another
3910 CFStringAppend(local
, CFSTR(" --> "));
3916 name
= CFStringCreateCopy(NULL
, local
);
3925 __SCNetworkInterfaceCopyXLocalizedDisplayName(SCNetworkInterfaceRef interface
)
3929 if (!isA_SCNetworkInterface(interface
)) {
3930 _SCErrorSet(kSCStatusInvalidArgument
);
3934 name
= copy_display_name(interface
, TRUE
, TRUE
);
3941 __SCNetworkInterfaceCopyXNonLocalizedDisplayName(SCNetworkInterfaceRef interface
)
3943 CFStringRef localized_name
;
3945 if (!isA_SCNetworkInterface(interface
)) {
3946 _SCErrorSet(kSCStatusInvalidArgument
);
3950 localized_name
= copy_display_name(interface
, FALSE
, TRUE
);
3951 return localized_name
;
3957 __SCNetworkInterfaceGetNonLocalizedDisplayName(SCNetworkInterfaceRef interface
)
3959 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3961 if (!isA_SCNetworkInterface(interface
)) {
3962 _SCErrorSet(kSCStatusInvalidArgument
);
3966 if (interfacePrivate
->name
== NULL
) {
3967 interfacePrivate
->name
= copy_display_name(interface
, FALSE
, FALSE
);
3970 return interfacePrivate
->name
;
3975 SCNetworkInterfaceGetLocalizedDisplayName(SCNetworkInterfaceRef interface
)
3977 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3979 if (!isA_SCNetworkInterface(interface
)) {
3980 _SCErrorSet(kSCStatusInvalidArgument
);
3984 if (interfacePrivate
->localized_name
== NULL
) {
3985 interfacePrivate
->localized_name
= copy_display_name(interface
, TRUE
, FALSE
);
3988 return interfacePrivate
->localized_name
;
3994 __SCNetworkInterfaceGetTemplateOverrides(SCNetworkInterfaceRef interface
, CFStringRef interfaceType
)
3996 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3997 CFDictionaryRef overrides
= NULL
;
3999 if (interfacePrivate
->overrides
!= NULL
) {
4000 overrides
= CFDictionaryGetValue(interfacePrivate
->overrides
, interfaceType
);
4008 SCNetworkInterfaceGetTypeID(void)
4010 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
); /* initialize runtime */
4011 return __kSCNetworkInterfaceTypeID
;
4017 __SCNetworkInterfaceSetDefaultConfiguration(SCNetworkSetRef set
,
4018 SCNetworkInterfaceRef interface
,
4019 CFStringRef defaultType
,
4020 CFDictionaryRef config
,
4023 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4026 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
4027 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4029 if (defaultType
== NULL
) {
4030 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
4031 if (defaultType
== NULL
) {
4036 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
4043 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
4044 SCNetworkSetGetSetID(set
), // set
4045 interfacePrivate
->entity_device
, // interface
4046 defaultType
); // entity
4048 ok
= __setPrefsConfiguration(interfacePrivate
->prefs
, path
, config
, FALSE
);
4051 // if configuration has been saved
4052 if (interfacePrivate
->unsaved
!= NULL
) {
4053 CFDictionaryRemoveValue(interfacePrivate
->unsaved
, defaultType
);
4054 if (CFDictionaryGetCount(interfacePrivate
->unsaved
) == 0) {
4055 CFRelease(interfacePrivate
->unsaved
);
4056 interfacePrivate
->unsaved
= NULL
;
4062 if (config
== NULL
) {
4063 // remember that we are clearing the configuration
4064 config
= (CFDictionaryRef
)kCFNull
;
4067 if (interfacePrivate
->unsaved
== NULL
) {
4068 interfacePrivate
->unsaved
= CFDictionaryCreateMutable(NULL
,
4070 &kCFTypeDictionaryKeyCallBacks
,
4071 &kCFTypeDictionaryValueCallBacks
);
4073 CFDictionarySetValue(interfacePrivate
->unsaved
, defaultType
, config
);
4076 _SCErrorSet(kSCStatusNoKey
);
4087 __SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface
,
4088 CFStringRef extendedType
,
4089 CFDictionaryRef config
,
4092 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4096 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
4097 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4099 if (extendedType
== NULL
) {
4100 extendedType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
4101 if (extendedType
== NULL
) {
4106 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
4110 paths
= copyConfigurationPaths(interfacePrivate
, extendedType
);
4111 if (paths
!= NULL
) {
4115 n
= CFArrayGetCount(paths
);
4116 for (i
= 0; i
< n
; i
++) {
4119 path
= CFArrayGetValueAtIndex(paths
, i
);
4120 ok
= __setPrefsConfiguration(interfacePrivate
->prefs
, path
, config
, FALSE
);
4127 // if configuration has been saved
4128 if (interfacePrivate
->unsaved
!= NULL
) {
4129 CFDictionaryRemoveValue(interfacePrivate
->unsaved
, extendedType
);
4130 if (CFDictionaryGetCount(interfacePrivate
->unsaved
) == 0) {
4131 CFRelease(interfacePrivate
->unsaved
);
4132 interfacePrivate
->unsaved
= NULL
;
4140 if (config
== NULL
) {
4141 // remember that we are clearing the configuration
4142 config
= (CFDictionaryRef
)kCFNull
;
4145 if (interfacePrivate
->unsaved
== NULL
) {
4146 interfacePrivate
->unsaved
= CFDictionaryCreateMutable(NULL
,
4148 &kCFTypeDictionaryKeyCallBacks
,
4149 &kCFTypeDictionaryValueCallBacks
);
4151 CFDictionarySetValue(interfacePrivate
->unsaved
, extendedType
, config
);
4154 _SCErrorSet(kSCStatusNoKey
);
4163 SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface
, CFDictionaryRef config
)
4165 CFStringRef defaultType
;
4167 if (!isA_SCNetworkInterface(interface
)) {
4168 _SCErrorSet(kSCStatusInvalidArgument
);
4172 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
4173 if (defaultType
== NULL
) {
4177 return __SCNetworkInterfaceSetConfiguration(interface
, defaultType
, config
, FALSE
);
4182 SCNetworkInterfaceSetExtendedConfiguration(SCNetworkInterfaceRef interface
,
4183 CFStringRef extendedType
,
4184 CFDictionaryRef config
)
4186 if (!isA_SCNetworkInterface(interface
)) {
4187 _SCErrorSet(kSCStatusInvalidArgument
);
4191 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, TRUE
)) {
4195 return __SCNetworkInterfaceSetConfiguration(interface
, extendedType
, config
, FALSE
);
4200 #pragma mark SCNetworkInterface [Refresh Configuration] API
4203 #ifndef kSCEntNetRefreshConfiguration
4204 #define kSCEntNetRefreshConfiguration CFSTR("RefreshConfiguration")
4205 #endif // kSCEntNetRefreshConfiguration
4208 _SCNetworkInterfaceForceConfigurationRefresh(CFStringRef ifName
)
4212 SCDynamicStoreRef store
;
4214 if (!isA_CFString(ifName
)) {
4215 _SCErrorSet(kSCStatusInvalidArgument
);
4219 store
= SCDynamicStoreCreate(NULL
, CFSTR("_SCNetworkInterfaceForceConfigurationRefresh"), NULL
, NULL
);
4220 if (store
== NULL
) {
4224 key
= SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL
,
4225 kSCDynamicStoreDomainState
,
4227 kSCEntNetRefreshConfiguration
);
4228 ok
= SCDynamicStoreNotifyValue(store
, key
);
4236 __SCNetworkInterfaceForceConfigurationRefresh_helper(SCPreferencesRef prefs
, CFStringRef ifName
)
4238 CFDataRef data
= NULL
;
4240 SCPreferencesPrivateRef prefsPrivate
= (SCPreferencesPrivateRef
)prefs
;
4241 uint32_t status
= kSCStatusOK
;
4242 CFDataRef reply
= NULL
;
4244 if (prefsPrivate
->helper
== -1) {
4245 ok
= __SCPreferencesCreate_helper(prefs
);
4251 // serialize the interface name
4252 ok
= _SCSerializeString(ifName
, &data
, NULL
, NULL
);
4257 // have the helper "refresh" the configuration
4258 status
= kSCStatusOK
;
4260 ok
= _SCHelperExec(prefsPrivate
->helper
,
4261 SCHELPER_MSG_INTERFACE_REFRESH
,
4265 if (data
!= NULL
) CFRelease(data
);
4270 if (status
!= kSCStatusOK
) {
4279 if (prefsPrivate
->helper
!= -1) {
4280 _SCHelperClose(prefsPrivate
->helper
);
4281 prefsPrivate
->helper
= -1;
4284 status
= kSCStatusAccessError
;
4289 _SCErrorSet(status
);
4295 SCNetworkInterfaceForceConfigurationRefresh(SCNetworkInterfaceRef interface
)
4298 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4300 if (!isA_SCNetworkInterface(interface
)) {
4301 _SCErrorSet(kSCStatusInvalidArgument
);
4305 ifName
= SCNetworkInterfaceGetBSDName(interface
);
4306 if (ifName
== NULL
) {
4307 _SCErrorSet(kSCStatusInvalidArgument
);
4311 if (interfacePrivate
->prefs
!= NULL
) {
4312 SCPreferencesRef prefs
= interfacePrivate
->prefs
;
4313 SCPreferencesPrivateRef prefsPrivate
= (SCPreferencesPrivateRef
)prefs
;
4315 if (prefsPrivate
->authorizationData
!= NULL
) {
4316 return __SCNetworkInterfaceForceConfigurationRefresh_helper(prefs
, ifName
);
4320 return _SCNetworkInterfaceForceConfigurationRefresh(ifName
);
4325 SCNetworkInterfaceRefreshConfiguration(CFStringRef ifName
)
4327 return _SCNetworkInterfaceForceConfigurationRefresh(ifName
);
4332 #pragma mark SCNetworkInterface Password APIs
4336 getPasswordID(CFDictionaryRef config
, CFStringRef serviceID
)
4338 CFStringRef unique_id
= NULL
;
4340 if (config
!= NULL
) {
4341 CFStringRef encryption
;
4343 encryption
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPasswordEncryption
);
4344 if (isA_CFString(encryption
) &&
4345 CFEqual(encryption
, kSCValNetPPPAuthPasswordEncryptionKeychain
)) {
4346 unique_id
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPassword
);
4349 if (unique_id
== NULL
) {
4350 unique_id
= serviceID
;
4358 copySharedSecretID(CFDictionaryRef config
, CFStringRef serviceID
)
4360 CFMutableStringRef shared_id
= NULL
;
4362 if (config
!= NULL
) {
4363 CFStringRef encryption
;
4365 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecretEncryption
);
4366 if (isA_CFString(encryption
) &&
4367 CFEqual(encryption
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) {
4368 shared_id
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecret
);
4369 if (shared_id
!= NULL
) {
4370 CFRetain(shared_id
);
4375 if (shared_id
== NULL
) {
4376 CFStringRef unique_id
;
4378 unique_id
= getPasswordID(config
, serviceID
);
4379 shared_id
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
4380 CFStringAppend(shared_id
, CFSTR(".SS"));
4388 copyXAuthID(CFDictionaryRef config
, CFStringRef serviceID
)
4390 CFMutableStringRef xauth_id
= NULL
;
4392 if (config
!= NULL
) {
4393 CFStringRef encryption
;
4395 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPasswordEncryption
);
4396 if (isA_CFString(encryption
) &&
4397 CFEqual(encryption
, kSCValNetIPSecXAuthPasswordEncryptionKeychain
)) {
4398 xauth_id
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPassword
);
4399 if (xauth_id
!= NULL
) {
4405 if (xauth_id
== NULL
) {
4406 CFStringRef unique_id
;
4408 unique_id
= getPasswordID(config
, serviceID
);
4409 xauth_id
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
4410 CFStringAppend(xauth_id
, CFSTR(".XAUTH"));
4418 checkInterfacePassword(SCNetworkInterfaceRef interface
,
4419 SCNetworkInterfacePasswordType passwordType
,
4420 SCPreferencesRef
*prefs
,
4421 CFStringRef
*serviceID
)
4423 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4425 if (!isA_SCNetworkInterface(interface
)) {
4429 *serviceID
= interfacePrivate
->serviceID
;
4430 if (*serviceID
== NULL
) {
4434 *prefs
= interfacePrivate
->prefs
;
4435 if (*prefs
== NULL
) {
4439 switch (passwordType
) {
4440 case kSCNetworkInterfacePasswordTypePPP
: {
4441 CFStringRef interfaceType
;
4443 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
4444 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
4452 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
4453 CFStringRef interfaceType
;
4455 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
4456 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
4457 interface
= SCNetworkInterfaceGetInterface(interface
);
4458 if (interface
!= NULL
) {
4459 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
4460 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
4461 // if PPP->L2TP interface
4465 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
4466 // if IPSec interface
4473 case kSCNetworkInterfacePasswordTypeEAPOL
: {
4477 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
4478 CFStringRef interfaceType
;
4480 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
4481 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
4482 // if IPSec interface
4497 _SCErrorSet(kSCStatusInvalidArgument
);
4503 SCNetworkInterfaceCheckPassword(SCNetworkInterfaceRef interface
,
4504 SCNetworkInterfacePasswordType passwordType
)
4506 Boolean exists
= FALSE
;
4507 SCPreferencesRef prefs
= NULL
;
4508 CFStringRef serviceID
= NULL
;
4510 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
4514 switch (passwordType
) {
4515 case kSCNetworkInterfacePasswordTypePPP
: {
4516 CFDictionaryRef config
;
4517 CFStringRef unique_id
;
4519 // get configuration
4520 config
= SCNetworkInterfaceGetConfiguration(interface
);
4523 unique_id
= getPasswordID(config
, serviceID
);
4526 exists
= __extract_password(prefs
,
4528 kSCPropNetPPPAuthPassword
,
4529 kSCPropNetPPPAuthPasswordEncryption
,
4530 kSCValNetPPPAuthPasswordEncryptionKeychain
,
4536 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
4537 CFDictionaryRef config
;
4539 CFStringRef shared_id
;
4541 // get configuration
4542 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
4544 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
4546 config
= SCNetworkInterfaceGetConfiguration(interface
);
4549 // get sharedSecret ID
4550 shared_id
= copySharedSecretID(config
, serviceID
);
4553 exists
= __extract_password(prefs
,
4555 kSCPropNetIPSecSharedSecret
,
4556 kSCPropNetIPSecSharedSecretEncryption
,
4557 kSCValNetIPSecSharedSecretEncryptionKeychain
,
4560 CFRelease(shared_id
);
4564 case kSCNetworkInterfacePasswordTypeEAPOL
: {
4565 CFDictionaryRef config
;
4566 CFStringRef unique_id
= NULL
;
4568 // get configuration
4569 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
4571 // get 802.1X identifier
4572 if (config
!= NULL
) {
4573 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
4575 if (!isA_CFString(unique_id
)) {
4580 exists
= _SCPreferencesSystemKeychainPasswordItemExists(prefs
, unique_id
);
4584 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
4585 CFDictionaryRef config
;
4586 CFStringRef xauth_id
;
4588 // get configuration
4589 config
= SCNetworkInterfaceGetConfiguration(interface
);
4592 xauth_id
= copyXAuthID(config
, serviceID
);
4595 exists
= __extract_password(prefs
,
4597 kSCPropNetIPSecXAuthPassword
,
4598 kSCPropNetIPSecXAuthPasswordEncryption
,
4599 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
4602 CFRelease(xauth_id
);
4607 _SCErrorSet(kSCStatusInvalidArgument
);
4616 SCNetworkInterfaceCopyPassword(SCNetworkInterfaceRef interface
,
4617 SCNetworkInterfacePasswordType passwordType
)
4619 CFDataRef password
= NULL
;
4620 SCPreferencesRef prefs
= NULL
;
4621 CFStringRef serviceID
= NULL
;
4623 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
4627 switch (passwordType
) {
4628 case kSCNetworkInterfacePasswordTypePPP
: {
4629 CFDictionaryRef config
;
4630 CFStringRef unique_id
;
4632 // get configuration
4633 config
= SCNetworkInterfaceGetConfiguration(interface
);
4636 unique_id
= getPasswordID(config
, serviceID
);
4639 (void) __extract_password(prefs
,
4641 kSCPropNetPPPAuthPassword
,
4642 kSCPropNetPPPAuthPasswordEncryption
,
4643 kSCValNetPPPAuthPasswordEncryptionKeychain
,
4649 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
4650 CFDictionaryRef config
;
4652 CFStringRef shared_id
;
4654 // get configuration
4655 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
4657 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
4659 config
= SCNetworkInterfaceGetConfiguration(interface
);
4662 // get sharedSecret ID
4663 shared_id
= copySharedSecretID(config
, serviceID
);
4666 (void) __extract_password(prefs
,
4668 kSCPropNetIPSecSharedSecret
,
4669 kSCPropNetIPSecSharedSecretEncryption
,
4670 kSCValNetIPSecSharedSecretEncryptionKeychain
,
4674 CFRelease(shared_id
);
4678 case kSCNetworkInterfacePasswordTypeEAPOL
: {
4679 CFDictionaryRef config
;
4680 CFStringRef unique_id
= NULL
;
4682 // get configuration
4683 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
4685 // get 802.1X identifier
4686 if (config
!= NULL
) {
4687 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
4689 if (!isA_CFString(unique_id
)) {
4690 _SCErrorSet(kSCStatusFailed
);
4695 password
= _SCPreferencesSystemKeychainPasswordItemCopy(prefs
, unique_id
);
4699 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
4700 CFDictionaryRef config
;
4701 CFStringRef xauth_id
;
4703 // get configuration
4704 config
= SCNetworkInterfaceGetConfiguration(interface
);
4707 xauth_id
= copyXAuthID(config
, serviceID
);
4710 (void) __extract_password(prefs
,
4712 kSCPropNetIPSecXAuthPassword
,
4713 kSCPropNetIPSecXAuthPasswordEncryption
,
4714 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
4717 CFRelease(xauth_id
);
4722 _SCErrorSet(kSCStatusInvalidArgument
);
4731 SCNetworkInterfaceRemovePassword(SCNetworkInterfaceRef interface
,
4732 SCNetworkInterfacePasswordType passwordType
)
4735 SCPreferencesRef prefs
= NULL
;
4736 CFStringRef serviceID
= NULL
;
4738 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
4742 switch (passwordType
) {
4743 case kSCNetworkInterfacePasswordTypePPP
: {
4744 CFDictionaryRef config
;
4745 CFDictionaryRef newConfig
= NULL
;
4746 CFStringRef unique_id
;
4748 // get configuration
4749 config
= SCNetworkInterfaceGetConfiguration(interface
);
4752 unique_id
= getPasswordID(config
, serviceID
);
4755 ok
= __remove_password(prefs
,
4757 kSCPropNetPPPAuthPassword
,
4758 kSCPropNetPPPAuthPasswordEncryption
,
4759 kSCValNetPPPAuthPasswordEncryptionKeychain
,
4763 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
4764 if (newConfig
!= NULL
) CFRelease(newConfig
);
4770 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
4771 CFDictionaryRef config
;
4773 CFDictionaryRef newConfig
= NULL
;
4774 CFStringRef shared_id
;
4776 // get configuration
4777 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
4779 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
4781 config
= SCNetworkInterfaceGetConfiguration(interface
);
4784 // get sharedSecret ID
4785 shared_id
= copySharedSecretID(config
, serviceID
);
4788 ok
= __remove_password(prefs
,
4790 kSCPropNetIPSecSharedSecret
,
4791 kSCPropNetIPSecSharedSecretEncryption
,
4792 kSCValNetIPSecSharedSecretEncryptionKeychain
,
4797 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
4801 ok
= SCNetworkInterfaceSetConfiguration(interface
,
4804 if (newConfig
!= NULL
) CFRelease(newConfig
);
4807 CFRelease(shared_id
);
4811 case kSCNetworkInterfacePasswordTypeEAPOL
: {
4812 CFDictionaryRef config
;
4813 CFStringRef unique_id
= NULL
;
4815 // get configuration
4816 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
4818 // get 802.1X identifier
4819 if (config
!= NULL
) {
4820 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
4822 if (!isA_CFString(unique_id
)) {
4823 _SCErrorSet(kSCStatusFailed
);
4828 ok
= _SCPreferencesSystemKeychainPasswordItemRemove(prefs
, unique_id
);
4832 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
4833 CFDictionaryRef config
;
4834 CFDictionaryRef newConfig
= NULL
;
4835 CFStringRef xauth_id
;
4837 // get configuration
4838 config
= SCNetworkInterfaceGetConfiguration(interface
);
4841 xauth_id
= copyXAuthID(config
, serviceID
);
4844 ok
= __remove_password(prefs
,
4846 kSCPropNetIPSecXAuthPassword
,
4847 kSCPropNetIPSecXAuthPasswordEncryption
,
4848 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
4852 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
4853 if (newConfig
!= NULL
) CFRelease(newConfig
);
4856 CFRelease(xauth_id
);
4861 _SCErrorSet(kSCStatusInvalidArgument
);
4870 SCNetworkInterfaceSetPassword(SCNetworkInterfaceRef interface
,
4871 SCNetworkInterfacePasswordType passwordType
,
4873 CFDictionaryRef options
)
4875 CFStringRef account
= NULL
;
4876 CFDictionaryRef config
;
4877 CFStringRef description
= NULL
;
4878 CFStringRef label
= NULL
;
4880 SCPreferencesRef prefs
= NULL
;
4881 CFStringRef serviceID
= NULL
;
4883 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
4887 switch (passwordType
) {
4888 case kSCNetworkInterfacePasswordTypePPP
: {
4889 SCNetworkServiceRef service
= NULL
;
4890 CFStringRef unique_id
;
4892 // get configuration
4893 config
= SCNetworkInterfaceGetConfiguration(interface
);
4896 unique_id
= getPasswordID(config
, serviceID
);
4898 // get "Account", "Name", "Kind"
4899 if (config
!= NULL
) {
4900 // auth name --> keychain "Account"
4901 account
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthName
);
4903 // PPP [user defined] "name" --> keychain "Name"
4904 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
4907 if (label
== NULL
) {
4908 // service name --> keychain "Name"
4909 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
4914 label
= SCNetworkServiceGetName(service
);
4915 if (label
== NULL
) {
4916 // interface name --> keychain "Name"
4917 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
4921 if (bundle
!= NULL
) {
4922 // "PPP Password" --> keychain "Kind"
4923 description
= CFBundleCopyLocalizedString(bundle
,
4924 CFSTR("KEYCHAIN_KIND_PPP_PASSWORD"),
4925 CFSTR("PPP Password"),
4930 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
4932 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
4933 (description
!= NULL
) ? description
: CFSTR("PPP Password"),
4938 CFMutableDictionaryRef newConfig
;
4940 if (config
!= NULL
) {
4941 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
4943 newConfig
= CFDictionaryCreateMutable(NULL
,
4945 &kCFTypeDictionaryKeyCallBacks
,
4946 &kCFTypeDictionaryValueCallBacks
);
4948 CFDictionarySetValue(newConfig
,
4949 kSCPropNetPPPAuthPassword
,
4951 CFDictionarySetValue(newConfig
,
4952 kSCPropNetPPPAuthPasswordEncryption
,
4953 kSCValNetPPPAuthPasswordEncryptionKeychain
);
4954 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
4955 CFRelease(newConfig
);
4958 if (description
!= NULL
) CFRelease(description
);
4959 if (service
!= NULL
) CFRelease(service
);
4963 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
4964 CFDictionaryRef baseConfig
= NULL
;
4966 SCNetworkServiceRef service
= NULL
;
4967 CFStringRef shared_id
;
4969 // get configuration
4970 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
4971 config
= SCNetworkInterfaceGetConfiguration(interface
);
4973 baseConfig
= config
;
4974 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
4977 // get sharedSecret ID
4978 shared_id
= copySharedSecretID(config
, serviceID
);
4980 // get "Account", "Name", "Kind"
4981 if (config
!= NULL
) {
4982 CFStringRef localIdentifier
;
4983 CFStringRef localIdentifierType
;
4985 if (CFDictionaryGetValueIfPresent(config
,
4986 kSCPropNetIPSecLocalIdentifierType
,
4987 (const void **)&localIdentifierType
)
4988 && CFEqual(localIdentifierType
, kSCValNetIPSecLocalIdentifierTypeKeyID
)
4989 && CFDictionaryGetValueIfPresent(config
,
4990 kSCPropNetIPSecLocalIdentifier
,
4991 (const void **)&localIdentifier
)
4992 && isA_CFString(localIdentifier
)) {
4993 // local identifier --> keychain "Account"
4994 account
= localIdentifier
;
4997 // PPP [user defined] "name" --> keychain "Name"
4999 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
5001 if (baseConfig
!= NULL
) {
5002 label
= CFDictionaryGetValue(baseConfig
, kSCPropUserDefinedName
);
5007 if (label
== NULL
) {
5008 // service name --> keychain "Name"
5009 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
5014 label
= SCNetworkServiceGetName(service
);
5015 if (label
== NULL
) {
5016 // interface name --> keychain "Name"
5017 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
5021 if (bundle
!= NULL
) {
5022 // "IPSec Shared Secret" --> keychain "Kind"
5023 description
= CFBundleCopyLocalizedString(bundle
,
5024 CFSTR("KEYCHAIN_KIND_IPSEC_SHARED_SECRET"),
5025 CFSTR("IPSec Shared Secret"),
5030 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
5032 (label
!= NULL
) ? label
: CFSTR("VPN Connection"),
5033 (description
!= NULL
) ? description
: CFSTR("IPSec Shared Secret"),
5038 CFMutableDictionaryRef newConfig
= NULL
;
5040 if (config
!= NULL
) {
5041 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
5043 newConfig
= CFDictionaryCreateMutable(NULL
,
5045 &kCFTypeDictionaryKeyCallBacks
,
5046 &kCFTypeDictionaryValueCallBacks
);
5048 CFDictionarySetValue(newConfig
,
5049 kSCPropNetIPSecSharedSecret
,
5051 CFDictionarySetValue(newConfig
,
5052 kSCPropNetIPSecSharedSecretEncryption
,
5053 kSCValNetIPSecSharedSecretEncryptionKeychain
);
5055 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
5059 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
5061 CFRelease(newConfig
);
5064 if (description
!= NULL
) CFRelease(description
);
5065 if (service
!= NULL
) CFRelease(service
);
5066 CFRelease(shared_id
);
5070 case kSCNetworkInterfacePasswordTypeEAPOL
: {
5071 CFStringRef account
= NULL
;
5072 CFStringRef unique_id
= NULL
;
5074 // get configuration
5075 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
5077 // get 802.1X identifier
5078 if (config
!= NULL
) {
5079 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
5081 if (isA_CFString(unique_id
)) {
5082 CFRetain(unique_id
);
5086 uuid
= CFUUIDCreate(NULL
);
5087 unique_id
= CFUUIDCreateString(NULL
, uuid
);
5091 // 802.1x UserName --> keychain "Account"
5092 if (config
!= NULL
) {
5093 account
= CFDictionaryGetValue(config
, kEAPClientPropUserName
);
5096 // get "Name", "Kind"
5097 if (bundle
!= NULL
) {
5098 CFStringRef interface_name
;
5100 // "Network Connection (%@)" --> keychain "Name"
5101 interface_name
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
5102 if (interface_name
!= NULL
) {
5103 CFStringRef label_fmt
;
5105 label_fmt
= CFBundleCopyLocalizedString(bundle
,
5106 CFSTR("KEYCHAIN_DESCRIPTION_EAPOL_INTERFACE"),
5107 CFSTR("Network Connection (%@)"),
5109 label
= CFStringCreateWithFormat(NULL
, NULL
, label_fmt
, interface_name
);
5110 CFRelease(label_fmt
);
5112 label
= CFBundleCopyLocalizedString(bundle
,
5113 CFSTR("KEYCHAIN_DESCRIPTION_EAPOL"),
5114 CFSTR("Network Connection"),
5118 // "802.1X Password" --> keychain "Kind"
5119 description
= CFBundleCopyLocalizedString(bundle
,
5120 CFSTR("KEYCHAIN_KIND_EAPOL"),
5121 CFSTR("802.1X Password"),
5126 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
5128 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
5129 (description
!= NULL
) ? description
: CFSTR("802.1X Password"),
5134 CFMutableDictionaryRef newConfig
= NULL
;
5136 if (config
!= NULL
) {
5137 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
5139 newConfig
= CFDictionaryCreateMutable(NULL
,
5141 &kCFTypeDictionaryKeyCallBacks
,
5142 &kCFTypeDictionaryValueCallBacks
);
5144 CFDictionarySetValue(newConfig
,
5145 kEAPClientPropUserPasswordKeychainItemID
,
5147 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
5150 CFRelease(newConfig
);
5153 CFRelease(unique_id
);
5154 if (label
!= NULL
) CFRelease(label
);
5155 if (description
!= NULL
) CFRelease(description
);
5159 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
5160 SCNetworkServiceRef service
= NULL
;
5161 CFStringRef xauth_id
;
5163 // get configuration
5164 config
= SCNetworkInterfaceGetConfiguration(interface
);
5167 xauth_id
= copyXAuthID(config
, serviceID
);
5169 // get "Account", "Name", "Kind"
5170 if (config
!= NULL
) {
5171 // auth name --> keychain "Account"
5172 account
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthName
);
5174 // IPSec [user defined] "name" --> keychain "Name"
5175 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
5178 if (label
== NULL
) {
5179 // service name --> keychain "Name"
5180 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
5185 label
= SCNetworkServiceGetName(service
);
5186 if (label
== NULL
) {
5187 // interface name --> keychain "Name"
5188 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
5192 if (bundle
!= NULL
) {
5193 // "IPSec XAuth Password" --> keychain "Kind"
5194 description
= CFBundleCopyLocalizedString(bundle
,
5195 CFSTR("KEYCHAIN_KIND_IPSEC_XAUTH_PASSWORD"),
5196 CFSTR("IPSec XAuth Password"),
5201 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
5203 (label
!= NULL
) ? label
: CFSTR("VPN Connection"),
5204 (description
!= NULL
) ? description
: CFSTR("IPSec XAuth Password"),
5209 CFMutableDictionaryRef newConfig
;
5211 if (config
!= NULL
) {
5212 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
5214 newConfig
= CFDictionaryCreateMutable(NULL
,
5216 &kCFTypeDictionaryKeyCallBacks
,
5217 &kCFTypeDictionaryValueCallBacks
);
5219 CFDictionarySetValue(newConfig
,
5220 kSCPropNetIPSecXAuthPassword
,
5222 CFDictionarySetValue(newConfig
,
5223 kSCPropNetIPSecXAuthPasswordEncryption
,
5224 kSCValNetIPSecXAuthPasswordEncryptionKeychain
);
5225 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
5226 CFRelease(newConfig
);
5229 CFRelease(xauth_id
);
5230 if (description
!= NULL
) CFRelease(description
);
5231 if (service
!= NULL
) CFRelease(service
);
5236 _SCErrorSet(kSCStatusInvalidArgument
);
5245 #pragma mark SCNetworkInterface [InterfaceNamer] SPIs
5248 SCNetworkInterfaceRef
5249 _SCNetworkInterfaceCreateWithIONetworkInterfaceObject(io_object_t if_obj
)
5251 SCNetworkInterfaceRef interface
= NULL
;
5253 /* initialize runtime */
5254 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5256 if (IOObjectConformsTo(if_obj
, kIONetworkInterfaceClass
)) {
5257 interface
= createInterface(if_obj
, processNetworkInterface
);
5258 } else if (IOObjectConformsTo(if_obj
, kIOSerialBSDServiceValue
)) {
5259 interface
= createInterface(if_obj
, processSerialInterface
);
5267 _SCNetworkInterfaceGetConfigurationAction(SCNetworkInterfaceRef interface
)
5269 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5271 return interfacePrivate
->configurationAction
;
5276 _SCNetworkInterfaceGetHardwareAddress(SCNetworkInterfaceRef interface
)
5278 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5280 return interfacePrivate
->address
;
5285 _SCNetworkInterfaceGetIOInterfaceType(SCNetworkInterfaceRef interface
)
5287 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5289 return interfacePrivate
->type
;
5294 _SCNetworkInterfaceGetIOInterfaceUnit(SCNetworkInterfaceRef interface
)
5296 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5298 return interfacePrivate
->unit
;
5303 _SCNetworkInterfaceGetIOPath(SCNetworkInterfaceRef interface
)
5305 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5307 return interfacePrivate
->path
;
5312 _SCNetworkInterfaceIsBuiltin(SCNetworkInterfaceRef interface
)
5314 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5316 return interfacePrivate
->builtin
;
5321 #pragma mark SCNetworkInterface SPIs
5325 _SCNetworkInterfaceCopySlashDevPath(SCNetworkInterfaceRef interface
)
5327 io_registry_entry_t device
;
5328 io_iterator_t device_iterator
= MACH_PORT_NULL
;
5329 CFStringRef device_path
= NULL
;
5330 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5332 CFStringRef match_keys
[2];
5333 CFTypeRef match_vals
[2];
5334 CFDictionaryRef match_dict
;
5335 CFDictionaryRef matching
;
5337 if (interfacePrivate
->entity_device
== NULL
) {
5341 if (interfacePrivate
->entity_device_unique
== NULL
) {
5345 match_keys
[0] = CFSTR(kIOTTYBaseNameKey
);
5346 match_vals
[0] = interfacePrivate
->entity_device
;
5347 match_dict
= CFDictionaryCreate(NULL
,
5348 (const void **)match_keys
,
5349 (const void **)match_vals
,
5351 &kCFTypeDictionaryKeyCallBacks
,
5352 &kCFTypeDictionaryValueCallBacks
);
5354 match_keys
[0] = CFSTR(kIOProviderClassKey
);
5355 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
5356 match_keys
[1] = CFSTR(kIOPropertyMatchKey
);
5357 match_vals
[1] = match_dict
;
5358 matching
= CFDictionaryCreate(NULL
,
5359 (const void **)match_keys
,
5360 (const void **)match_vals
,
5361 sizeof(match_keys
)/sizeof(match_keys
[0]),
5362 &kCFTypeDictionaryKeyCallBacks
,
5363 &kCFTypeDictionaryValueCallBacks
);
5364 CFRelease(match_dict
);
5366 // note: this "matching" dictionary will be consumed by the call to IOServiceGetMatchingServices
5367 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &device_iterator
);
5368 if (kr
!= kIOReturnSuccess
) {
5369 SCLog(TRUE
, LOG_DEBUG
, CFSTR("IOServiceGetMatchingServices() failed, kr = 0x%x"), kr
);
5373 while ((device_path
== NULL
) &&
5374 ((device
= IOIteratorNext(device_iterator
)) != MACH_PORT_NULL
)) {
5375 CFDictionaryRef overrides
;
5377 overrides
= IORegistryEntrySearchCFProperty(device
,
5379 CFSTR("DeviceModemOverrides"),
5381 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
5382 if (overrides
!= NULL
) {
5383 if (isA_CFDictionary(overrides
)) {
5384 CFStringRef matchIdentifier
;
5386 matchIdentifier
= CFDictionaryGetValue(overrides
, CFSTR("UniqueIdentifier"));
5387 if (isA_CFString(matchIdentifier
) &&
5388 CFEqual(interfacePrivate
->entity_device_unique
, matchIdentifier
)) {
5389 device_path
= IORegistryEntryCreateCFProperty(device
,
5390 CFSTR(kIOTTYDeviceKey
),
5395 CFRelease(overrides
);
5397 IOObjectRelease(device
);
5400 IOObjectRelease(device_iterator
);
5404 if (device_path
== NULL
) {
5405 // if we haven't found an exact match to our UniqueIdentifier
5406 // so we simply return the base name.
5407 device_path
= SCNetworkInterfaceGetBSDName(interface
);
5408 if (device_path
!= NULL
) {
5409 CFRetain(device_path
);
5418 _SCNetworkInterfaceIsBluetoothPAN(SCNetworkInterfaceRef interface
)
5420 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5422 return (interfacePrivate
->sort_order
== kSortBluetoothPAN
);
5427 _SCNetworkInterfaceIsModemV92(SCNetworkInterfaceRef interface
)
5429 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5431 return interfacePrivate
->modemIsV92
;
5436 _SCNetworkInterfaceIsTethered(SCNetworkInterfaceRef interface
)
5438 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5440 return (interfacePrivate
->sort_order
== kSortTethered
);
5445 #pragma mark SCNetworkInterface [internal] SPIs
5449 SCNetworkInterfacePrivateRef
5450 __SCNetworkInterfaceCreateCopy(CFAllocatorRef allocator
,
5451 SCNetworkInterfaceRef interface
,
5452 SCPreferencesRef prefs
,
5453 CFStringRef serviceID
)
5455 SCNetworkInterfacePrivateRef oldPrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5456 SCNetworkInterfacePrivateRef newPrivate
;
5458 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5459 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5461 if (interface
== kSCNetworkInterfaceIPv4
) {
5462 return (SCNetworkInterfacePrivateRef
)CFRetain(interface
);
5465 newPrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, prefs
, serviceID
, NULL
);
5466 newPrivate
->interface_type
= oldPrivate
->interface_type
;
5467 if (oldPrivate
->interface
!= NULL
) {
5468 newPrivate
->interface
= (SCNetworkInterfaceRef
)__SCNetworkInterfaceCreateCopy(NULL
, // allocator
5469 oldPrivate
->interface
, // interface
5470 prefs
, // [new] prefs
5471 serviceID
); // [new] serviceID
5473 if (oldPrivate
->name
!= NULL
) {
5474 newPrivate
->name
= CFRetain(oldPrivate
->name
);
5476 if (oldPrivate
->localized_name
!= NULL
) {
5477 newPrivate
->localized_name
= CFRetain(oldPrivate
->localized_name
);
5479 newPrivate
->localized_key
= oldPrivate
->localized_key
;
5480 if (oldPrivate
->localized_arg1
!= NULL
) {
5481 newPrivate
->localized_arg1
= CFRetain(oldPrivate
->localized_arg1
);
5483 if (oldPrivate
->localized_arg2
!= NULL
) {
5484 newPrivate
->localized_arg2
= CFRetain(oldPrivate
->localized_arg2
);
5486 if (oldPrivate
->unsaved
!= NULL
) {
5487 newPrivate
->unsaved
= CFDictionaryCreateMutableCopy(NULL
, 0, oldPrivate
->unsaved
);
5489 if (oldPrivate
->entity_device
!= NULL
) {
5490 newPrivate
->entity_device
= CFRetain(oldPrivate
->entity_device
);
5492 if (oldPrivate
->entity_device_unique
!= NULL
) {
5493 newPrivate
->entity_device_unique
= CFRetain(oldPrivate
->entity_device_unique
);
5495 newPrivate
->entity_type
= oldPrivate
->entity_type
;
5496 newPrivate
->entity_subtype
= oldPrivate
->entity_subtype
;
5497 if (oldPrivate
->supported_interface_types
!= NULL
) {
5498 newPrivate
->supported_interface_types
= CFArrayCreateMutableCopy(NULL
, 0, oldPrivate
->supported_interface_types
);
5500 if (oldPrivate
->supported_protocol_types
!= NULL
) {
5501 newPrivate
->supported_protocol_types
= CFArrayCreateMutableCopy(NULL
, 0, oldPrivate
->supported_protocol_types
);
5503 if (oldPrivate
->address
!= NULL
) {
5504 newPrivate
->address
= CFRetain(oldPrivate
->address
);
5506 newPrivate
->builtin
= oldPrivate
->builtin
;
5507 if (oldPrivate
->configurationAction
!= NULL
) {
5508 newPrivate
->configurationAction
= CFRetain(oldPrivate
->configurationAction
);
5510 if (oldPrivate
->location
!= NULL
) {
5511 newPrivate
->location
= CFRetain(oldPrivate
->location
);
5513 if (oldPrivate
->path
!= NULL
) {
5514 newPrivate
->path
= CFRetain(oldPrivate
->path
);
5516 if (oldPrivate
->overrides
!= NULL
) {
5517 newPrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, oldPrivate
->overrides
);
5519 newPrivate
->modemIsV92
= oldPrivate
->modemIsV92
;
5520 if (oldPrivate
->type
!= NULL
) {
5521 newPrivate
->type
= CFRetain(oldPrivate
->type
);
5523 if (oldPrivate
->unit
!= NULL
) {
5524 newPrivate
->unit
= CFRetain(oldPrivate
->unit
);
5526 newPrivate
->sort_order
= oldPrivate
->sort_order
;
5527 #if !TARGET_OS_IPHONE
5528 newPrivate
->supportsBond
= oldPrivate
->supportsBond
;
5529 if (oldPrivate
->bond
.interfaces
!= NULL
) {
5530 newPrivate
->bond
.interfaces
= CFRetain(oldPrivate
->bond
.interfaces
);
5532 if (oldPrivate
->bond
.mode
!= NULL
) {
5533 newPrivate
->bond
.mode
= CFRetain(oldPrivate
->bond
.mode
);
5535 if (oldPrivate
->bond
.options
!= NULL
) {
5536 newPrivate
->bond
.options
= CFRetain(oldPrivate
->bond
.options
);
5538 newPrivate
->supportsVLAN
= oldPrivate
->supportsVLAN
;
5539 if (oldPrivate
->vlan
.interface
!= NULL
) {
5540 newPrivate
->vlan
.interface
= CFRetain(oldPrivate
->vlan
.interface
);
5542 if (oldPrivate
->vlan
.tag
!= NULL
) {
5543 newPrivate
->vlan
.tag
= CFRetain(oldPrivate
->vlan
.tag
);
5545 if (oldPrivate
->vlan
.options
!= NULL
) {
5546 newPrivate
->vlan
.options
= CFRetain(oldPrivate
->vlan
.options
);
5548 #endif // !TARGET_OS_IPHONE
5556 __SCNetworkInterfaceCopyDeepConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
)
5558 CFMutableArrayRef configs
;
5560 configs
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
5562 while (interface
!= NULL
) {
5563 CFStringRef defaultType
;
5564 CFMutableDictionaryRef interfaceConfiguration
;
5566 interfaceConfiguration
= CFDictionaryCreateMutable(NULL
,
5568 &kCFTypeDictionaryKeyCallBacks
,
5569 &kCFTypeDictionaryValueCallBacks
);
5571 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5572 if (defaultType
!= NULL
) {
5573 CFDictionaryRef config
;
5574 CFArrayRef extendedTypes
;
5577 config
= __SCNetworkInterfaceGetConfiguration(interface
, defaultType
);
5579 config
= __SCNetworkInterfaceGetDefaultConfiguration(set
, interface
);
5581 if (config
== NULL
) {
5582 config
= (CFDictionaryRef
)kCFNull
;
5584 CFDictionarySetValue(interfaceConfiguration
, defaultType
, config
);
5586 extendedTypes
= extendedConfigurationTypes(interface
);
5587 if (extendedTypes
!= NULL
) {
5591 n
= CFArrayGetCount(extendedTypes
);
5592 for (i
= 0; i
< n
; i
++) {
5593 CFStringRef extendedType
;
5595 extendedType
= CFArrayGetValueAtIndex(extendedTypes
, i
);
5596 config
= __SCNetworkInterfaceGetConfiguration(interface
, extendedType
);
5597 if (config
== NULL
) {
5598 config
= (CFDictionaryRef
)kCFNull
;
5600 CFDictionarySetValue(interfaceConfiguration
, extendedType
, config
);
5603 CFRelease(extendedTypes
);
5607 CFArrayAppendValue(configs
, interfaceConfiguration
);
5608 CFRelease(interfaceConfiguration
);
5610 interface
= SCNetworkInterfaceGetInterface(interface
);
5619 __SCNetworkInterfaceSetDeepConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
, CFArrayRef configs
)
5623 for (i
= 0; interface
!= NULL
; i
++) {
5624 CFStringRef defaultType
;
5625 CFDictionaryRef interfaceConfiguration
;
5627 interfaceConfiguration
= (configs
!= NULL
) ? CFArrayGetValueAtIndex(configs
, i
) : NULL
;
5629 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5630 if (defaultType
!= NULL
) {
5631 CFDictionaryRef config
;
5632 CFArrayRef extendedTypes
;
5634 config
= (interfaceConfiguration
!= NULL
) ? CFDictionaryGetValue(interfaceConfiguration
, defaultType
)
5636 if (config
== (CFDictionaryRef
)kCFNull
) {
5640 // if service is not associated with the set
5641 if (!__SCNetworkInterfaceSetConfiguration(interface
, defaultType
, config
, TRUE
)) {
5642 SCLog(TRUE
, LOG_DEBUG
,
5643 CFSTR("__SCNetworkInterfaceSetDeepConfiguration __SCNetworkInterfaceSetConfiguration() failed, interface=%@, type=%@"),
5648 // apply default configuration to this set
5649 if (!__SCNetworkInterfaceSetDefaultConfiguration(set
, interface
, defaultType
, config
, TRUE
)) {
5650 SCLog(TRUE
, LOG_DEBUG
,
5651 CFSTR("__SCNetworkInterfaceSetDeepConfiguration __SCNetworkInterfaceSetDefaultConfiguration() failed, interface=%@, type=%@"),
5657 extendedTypes
= extendedConfigurationTypes(interface
);
5658 if (extendedTypes
!= NULL
) {
5662 n
= CFArrayGetCount(extendedTypes
);
5663 for (j
= 0; j
< n
; j
++) {
5664 CFStringRef extendedType
;
5666 extendedType
= CFArrayGetValueAtIndex(extendedTypes
, j
);
5667 config
= (interfaceConfiguration
!= NULL
) ? CFDictionaryGetValue(interfaceConfiguration
, extendedType
)
5669 if (config
== (CFDictionaryRef
)kCFNull
) {
5672 if (!__SCNetworkInterfaceSetConfiguration(interface
, extendedType
, config
, TRUE
)) {
5673 SCLog(TRUE
, LOG_DEBUG
,
5674 CFSTR("__SCNetworkInterfaceSetDeepConfiguration __SCNetworkInterfaceSetConfiguration() failed, interface=%@, type=%@"),
5680 CFRelease(extendedTypes
);
5684 interface
= SCNetworkInterfaceGetInterface(interface
);