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 { NULL
, 0, 0 }, // usb { name, vid, pid }
175 kSortUnknown
, // sort_order
176 #if !TARGET_OS_IPHONE
177 FALSE
, // supportsBond
178 { NULL
, NULL
}, // bond { interfaces, options }
179 FALSE
, // supportsVLAN
180 { NULL
, NULL
, NULL
} // vlan { interface, tag, options }
181 #endif // !TARGET_OS_IPHONE
184 const SCNetworkInterfaceRef kSCNetworkInterfaceIPv4
= (SCNetworkInterfaceRef
)&__kSCNetworkInterfaceIPv4
;
187 #pragma mark SCNetworkInterface configuration details
196 #define doOverIP do6to4|doL2TP|doPPTP|doIPSec
198 #if !TARGET_OS_IPHONE
199 #define doAppleTalk 1<<0
200 #else // !TARGET_OS_IPHONE
201 #define doAppleTalk 0
202 #endif // !TARGET_OS_IPHONE
206 #define doProxies 1<<4
207 #if !TARGET_OS_IPHONE
209 #else // !TARGET_OS_IPHONE
211 #endif // !TARGET_OS_IPHONE
213 static const struct {
214 const CFStringRef
*interface_type
;
215 const CFStringRef
*entity_hardware
;
216 Boolean per_interface_config
;
217 uint32_t supported_interfaces
;
218 const CFStringRef
*ppp_subtype
;
219 uint32_t supported_protocols
;
220 } configurations
[] = {
221 // interface type entity_hardware if config? interface types PPP sub-type interface protocols
222 // ===================================== ================= ========== =============== ======================================= =========================================
223 { &kSCNetworkInterfaceType6to4
, &kSCEntNet6to4
, FALSE
, doNone
, NULL
, doIPv6
},
224 { &kSCNetworkInterfaceTypeBluetooth
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
225 #if !TARGET_OS_IPHONE
226 { &kSCNetworkInterfaceTypeBond
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doAppleTalk
|doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
227 #endif // !TARGET_OS_IPHONE
228 { &kSCNetworkInterfaceTypeEthernet
, &kSCEntNetEthernet
, TRUE
, doPPP
, &kSCValNetInterfaceSubTypePPPoE
, doAppleTalk
|doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
229 { &kSCNetworkInterfaceTypeFireWire
, &kSCEntNetFireWire
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
230 { &kSCNetworkInterfaceTypeIEEE80211
, &kSCEntNetAirPort
, TRUE
, doPPP
, &kSCValNetInterfaceSubTypePPPoE
, doAppleTalk
|doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
231 { &kSCNetworkInterfaceTypeIPSec
, &kSCEntNetIPSec
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
232 { &kSCNetworkInterfaceTypeIrDA
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
233 { &kSCNetworkInterfaceTypeL2TP
, NULL
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypeL2TP
, doNone
},
234 { &kSCNetworkInterfaceTypeModem
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
235 { &kSCNetworkInterfaceTypePPP
, &kSCEntNetPPP
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
236 { &kSCNetworkInterfaceTypePPTP
, NULL
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPTP
, doNone
},
237 { &kSCNetworkInterfaceTypeSerial
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
238 #if !TARGET_OS_IPHONE
239 { &kSCNetworkInterfaceTypeVLAN
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doAppleTalk
|doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
240 #endif // !TARGET_OS_IPHONE
241 { &kSCNetworkInterfaceTypeWWAN
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
242 // ===================================== ================= ========== =============== ======================================= =========================================
243 { &kSCNetworkInterfaceTypeIPv4
, NULL
, FALSE
, doOverIP
, NULL
, doNone
}
247 #define NETWORKINTERFACE_LOCALIZATIONS CFSTR("NetworkInterface")
248 static CFBundleRef bundle
= NULL
;
251 static CFTypeID __kSCNetworkInterfaceTypeID
= _kCFRuntimeNotATypeID
;
254 static const CFRuntimeClass __SCNetworkInterfaceClass
= {
256 "SCNetworkInterface", // className
259 __SCNetworkInterfaceDeallocate
, // dealloc
260 __SCNetworkInterfaceEqual
, // equal
261 __SCNetworkInterfaceHash
, // hash
262 NULL
, // copyFormattingDesc
263 __SCNetworkInterfaceCopyDescription
// copyDebugDesc
267 static pthread_once_t initialized
= PTHREAD_ONCE_INIT
;
268 static pthread_once_t iokit_quiet
= PTHREAD_ONCE_INIT
;
271 static mach_port_t masterPort
= MACH_PORT_NULL
;
275 __SCNetworkInterfaceCopyDescription(CFTypeRef cf
)
277 CFAllocatorRef allocator
= CFGetAllocator(cf
);
278 CFMutableStringRef result
;
279 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
281 result
= CFStringCreateMutable(allocator
, 0);
282 CFStringAppendFormat(result
, NULL
, CFSTR("<SCNetworkInterface %p [%p]> {"), cf
, allocator
);
283 CFStringAppendFormat(result
, NULL
, CFSTR("type = %@"), interfacePrivate
->interface_type
);
284 CFStringAppendFormat(result
, NULL
, CFSTR(", entity_device = %@"), interfacePrivate
->entity_device
);
285 if (interfacePrivate
->entity_device_unique
!= NULL
) {
286 CFStringAppendFormat(result
, NULL
, CFSTR("+%@"), interfacePrivate
->entity_device_unique
);
288 CFStringAppendFormat(result
, NULL
, CFSTR(", entity_type = %@"), interfacePrivate
->entity_type
);
289 if (interfacePrivate
->entity_subtype
!= NULL
) {
290 CFStringAppendFormat(result
, NULL
, CFSTR(" / %@"), interfacePrivate
->entity_subtype
);
292 if (interfacePrivate
->name
!= NULL
) {
293 CFStringAppendFormat(result
, NULL
, CFSTR(", name = %@"), interfacePrivate
->name
);
295 if (interfacePrivate
->localized_name
!= NULL
) {
296 CFStringAppendFormat(result
, NULL
, CFSTR(", name(l) = %@"), interfacePrivate
->localized_name
);
298 if (interfacePrivate
->localized_key
!= NULL
) {
299 CFStringAppendFormat(result
, NULL
, CFSTR(", name(k) = \"%@\""), interfacePrivate
->localized_key
);
300 if (interfacePrivate
->localized_arg1
!= NULL
) {
301 CFStringAppendFormat(result
, NULL
, CFSTR("+\"%@\""), interfacePrivate
->localized_arg1
);
303 if (interfacePrivate
->localized_arg2
!= NULL
) {
304 CFStringAppendFormat(result
, NULL
, CFSTR("+\"%@\""), interfacePrivate
->localized_arg2
);
308 if (interfacePrivate
->address
!= NULL
) {
313 CFStringAppendFormat(result
, NULL
, CFSTR(", address = 0x"));
315 data
= CFDataGetBytePtr(interfacePrivate
->address
);
316 dataLen
= CFDataGetLength(interfacePrivate
->address
);
317 for (i
= 0; i
< dataLen
; i
++) {
318 CFStringAppendFormat(result
, NULL
, CFSTR("%02x"), data
[i
]);
321 CFStringAppendFormat(result
, NULL
, CFSTR(", builtin = %s"), interfacePrivate
->builtin
? "TRUE" : "FALSE");
322 if (interfacePrivate
->modemIsV92
) {
323 CFStringAppendFormat(result
, NULL
, CFSTR(", v.92"));
325 if (interfacePrivate
->location
!= NULL
) {
326 CFStringAppendFormat(result
, NULL
, CFSTR(", location = %@"), interfacePrivate
->location
);
328 if (interfacePrivate
->path
!= NULL
) {
329 CFStringAppendFormat(result
, NULL
, CFSTR(", path = %@"), interfacePrivate
->path
);
331 if (interfacePrivate
->type
!= NULL
) {
332 CFStringAppendFormat(result
, NULL
, CFSTR(", type = %@"), interfacePrivate
->type
);
334 if (interfacePrivate
->unit
!= NULL
) {
335 CFStringAppendFormat(result
, NULL
, CFSTR(", unit = %@"), interfacePrivate
->unit
);
337 if ((interfacePrivate
->usb
.vid
!= NULL
) || (interfacePrivate
->usb
.pid
!= NULL
)) {
341 if (!isA_CFNumber(interfacePrivate
->usb
.pid
) ||
342 !CFNumberGetValue(interfacePrivate
->usb
.vid
, kCFNumberIntType
, &pid
)) {
345 if (!isA_CFNumber(interfacePrivate
->usb
.vid
) ||
346 !CFNumberGetValue(interfacePrivate
->usb
.vid
, kCFNumberIntType
, &vid
)) {
350 CFStringAppendFormat(result
, NULL
, CFSTR(", USB%s%@ vid/pid = 0x%0x/0x%0x"),
351 interfacePrivate
->usb
.name
!= NULL
? " name = " : "",
352 interfacePrivate
->usb
.name
!= NULL
? interfacePrivate
->usb
.name
: CFSTR(""),
353 interfacePrivate
->usb
.vid
,
354 interfacePrivate
->usb
.pid
);
356 if (interfacePrivate
->configurationAction
!= NULL
) {
357 CFStringAppendFormat(result
, NULL
, CFSTR(", action = %@"), interfacePrivate
->configurationAction
);
359 if (interfacePrivate
->overrides
!= NULL
) {
360 CFStringAppendFormat(result
, NULL
, CFSTR(", overrides = %p"), interfacePrivate
->overrides
);
362 CFStringAppendFormat(result
, NULL
, CFSTR(", order = %d"), interfacePrivate
->sort_order
);
363 if (interfacePrivate
->prefs
!= NULL
) {
364 CFStringAppendFormat(result
, NULL
, CFSTR(", prefs = %p"), interfacePrivate
->prefs
);
366 if (interfacePrivate
->serviceID
!= NULL
) {
367 CFStringAppendFormat(result
, NULL
, CFSTR(", service = %@"), interfacePrivate
->serviceID
);
369 if (interfacePrivate
->interface
!= NULL
) {
370 CFStringAppendFormat(result
, NULL
, CFSTR(", interface = %@"), interfacePrivate
->interface
);
372 if (interfacePrivate
->unsaved
!= NULL
) {
373 CFStringAppendFormat(result
, NULL
, CFSTR(", unsaved = %@"), interfacePrivate
->unsaved
);
375 #if !TARGET_OS_IPHONE
376 if (interfacePrivate
->bond
.interfaces
!= NULL
) {
380 n
= CFArrayGetCount(interfacePrivate
->bond
.interfaces
);
381 for (i
= 0; i
< n
; i
++) {
382 SCNetworkInterfaceRef member
;
384 member
= CFArrayGetValueAtIndex(interfacePrivate
->bond
.interfaces
, i
);
385 CFStringAppendFormat(result
, NULL
,
387 (i
== 0) ? ", interfaces = " : ", ",
388 SCNetworkInterfaceGetBSDName(member
));
391 if (interfacePrivate
->bond
.mode
!= NULL
) {
392 CFStringAppendFormat(result
, NULL
, CFSTR(", mode = %@"), interfacePrivate
->bond
.mode
);
394 if (interfacePrivate
->bond
.options
!= NULL
) {
395 CFStringAppendFormat(result
, NULL
, CFSTR(", options = %@"), interfacePrivate
->bond
.options
);
397 if (interfacePrivate
->bond
.mode
!= NULL
) {
398 CFStringAppendFormat(result
, NULL
, CFSTR(", mode = %@"), interfacePrivate
->bond
.mode
);
400 if (interfacePrivate
->vlan
.interface
!= NULL
) {
401 CFStringAppendFormat(result
, NULL
,
402 CFSTR(", interface = %@"),
403 SCNetworkInterfaceGetBSDName(interfacePrivate
->vlan
.interface
));
405 if (interfacePrivate
->vlan
.tag
!= NULL
) {
406 CFStringAppendFormat(result
, NULL
, CFSTR(", tag = %@"), interfacePrivate
->vlan
.tag
);
408 if (interfacePrivate
->vlan
.options
!= NULL
) {
409 CFStringAppendFormat(result
, NULL
, CFSTR(", options = %@"), interfacePrivate
->vlan
.options
);
411 #endif // !TARGET_OS_IPHONE
412 CFStringAppendFormat(result
, NULL
, CFSTR("}"));
419 __SCNetworkInterfaceDeallocate(CFTypeRef cf
)
421 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
423 /* release resources */
425 if (interfacePrivate
->interface
!= NULL
)
426 CFRelease(interfacePrivate
->interface
);
428 if (interfacePrivate
->name
!= NULL
)
429 CFRelease(interfacePrivate
->name
);
431 if (interfacePrivate
->localized_name
!= NULL
)
432 CFRelease(interfacePrivate
->localized_name
);
434 if (interfacePrivate
->localized_arg1
!= NULL
)
435 CFRelease(interfacePrivate
->localized_arg1
);
437 if (interfacePrivate
->localized_arg2
!= NULL
)
438 CFRelease(interfacePrivate
->localized_arg2
);
440 if (interfacePrivate
->prefs
!= NULL
)
441 CFRelease(interfacePrivate
->prefs
);
443 if (interfacePrivate
->serviceID
!= NULL
)
444 CFRelease(interfacePrivate
->serviceID
);
446 if (interfacePrivate
->unsaved
!= NULL
)
447 CFRelease(interfacePrivate
->unsaved
);
449 if (interfacePrivate
->entity_device
!= NULL
)
450 CFRelease(interfacePrivate
->entity_device
);
452 if (interfacePrivate
->entity_device_unique
!= NULL
)
453 CFRelease(interfacePrivate
->entity_device_unique
);
455 if (interfacePrivate
->supported_interface_types
!= NULL
)
456 CFRelease(interfacePrivate
->supported_interface_types
);
458 if (interfacePrivate
->supported_protocol_types
!= NULL
)
459 CFRelease(interfacePrivate
->supported_protocol_types
);
461 if (interfacePrivate
->address
!= NULL
)
462 CFRelease(interfacePrivate
->address
);
464 if (interfacePrivate
->addressString
!= NULL
)
465 CFRelease(interfacePrivate
->addressString
);
467 if (interfacePrivate
->location
!= NULL
)
468 CFRelease(interfacePrivate
->location
);
470 if (interfacePrivate
->path
!= NULL
)
471 CFRelease(interfacePrivate
->path
);
473 if (interfacePrivate
->configurationAction
!= NULL
)
474 CFRelease(interfacePrivate
->configurationAction
);
476 if (interfacePrivate
->overrides
!= NULL
)
477 CFRelease(interfacePrivate
->overrides
);
479 if (interfacePrivate
->type
!= NULL
)
480 CFRelease(interfacePrivate
->type
);
482 if (interfacePrivate
->unit
!= NULL
)
483 CFRelease(interfacePrivate
->unit
);
485 if (interfacePrivate
->usb
.name
!= NULL
)
486 CFRelease(interfacePrivate
->usb
.name
);
488 if (interfacePrivate
->usb
.pid
!= NULL
)
489 CFRelease(interfacePrivate
->usb
.pid
);
491 if (interfacePrivate
->usb
.vid
!= NULL
)
492 CFRelease(interfacePrivate
->usb
.vid
);
494 #if !TARGET_OS_IPHONE
495 if (interfacePrivate
->bond
.interfaces
!= NULL
)
496 CFRelease(interfacePrivate
->bond
.interfaces
);
498 if (interfacePrivate
->bond
.mode
!= NULL
)
499 CFRelease(interfacePrivate
->bond
.mode
);
501 if (interfacePrivate
->bond
.options
!= NULL
)
502 CFRelease(interfacePrivate
->bond
.options
);
504 if (interfacePrivate
->vlan
.interface
!= NULL
)
505 CFRelease(interfacePrivate
->vlan
.interface
);
507 if (interfacePrivate
->vlan
.tag
!= NULL
)
508 CFRelease(interfacePrivate
->vlan
.tag
);
510 if (interfacePrivate
->vlan
.options
!= NULL
)
511 CFRelease(interfacePrivate
->vlan
.options
);
512 #endif // !TARGET_OS_IPHONE
519 __SCNetworkInterfaceEqual(CFTypeRef cf1
, CFTypeRef cf2
)
521 SCNetworkInterfacePrivateRef if1
= (SCNetworkInterfacePrivateRef
)cf1
;
522 SCNetworkInterfacePrivateRef if2
= (SCNetworkInterfacePrivateRef
)cf2
;
527 if (!CFEqual(if1
->interface_type
, if2
->interface_type
)) {
528 return FALSE
; // if not the same interface type
531 if (!_SC_CFEqual(if1
->entity_device
, if2
->entity_device
)) {
532 return FALSE
; // if not the same device
535 if ((if1
->entity_device_unique
!= NULL
) && (if2
->entity_device_unique
!= NULL
)) {
536 if (!_SC_CFEqual(if1
->entity_device_unique
, if2
->entity_device_unique
)) {
537 return FALSE
; // if not the same device unique identifier
539 } else if ((if1
->entity_device_unique
!= NULL
) || (if2
->entity_device_unique
!= NULL
)) {
543 name1
= __SCNetworkInterfaceGetNonLocalizedDisplayName((SCNetworkInterfaceRef
)if1
);
544 name2
= __SCNetworkInterfaceGetNonLocalizedDisplayName((SCNetworkInterfaceRef
)if2
);
545 if ((name1
!= NULL
) && (name2
!= NULL
) && !_SC_CFEqual(name1
, name2
)) {
546 return FALSE
; // if same device but not the same display name
550 #if !TARGET_OS_IPHONE
551 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeBond
)) {
552 if (!_SC_CFEqual(if1
->bond
.interfaces
, if2
->bond
.interfaces
)) {
553 return FALSE
; // if not the same interfaces
555 if (!_SC_CFEqual(if1
->bond
.mode
, if2
->bond
.mode
)) {
556 return FALSE
; // if not the same mode
560 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeVLAN
)) {
561 if (!_SC_CFEqual(if1
->vlan
.interface
, if2
->vlan
.interface
)) {
562 return FALSE
; // if not the same physical interface
564 if (!_SC_CFEqual(if1
->vlan
.tag
, if2
->vlan
.tag
)) {
565 return FALSE
; // if not the same tag
568 #endif // !TARGET_OS_IPHONE
570 if (!_SC_CFEqual(if1
->interface
, if2
->interface
)) {
571 return FALSE
; // if not the same layering
579 __SCNetworkInterfaceHash(CFTypeRef cf
)
582 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
584 if (interfacePrivate
->entity_device
!= NULL
) {
585 if (interfacePrivate
->entity_device_unique
== NULL
) {
586 hash
= CFHash(interfacePrivate
->entity_device
);
590 str
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@+%@"),
591 interfacePrivate
->entity_device
,
592 interfacePrivate
->entity_device_unique
);
603 __SCNetworkInterfaceInitialize(void)
608 __kSCNetworkInterfaceTypeID
= _CFRuntimeRegisterClass(&__SCNetworkInterfaceClass
);
610 // initialize __kSCNetworkInterfaceIPv4
611 _CFRuntimeSetInstanceTypeID(&__kSCNetworkInterfaceIPv4
, __kSCNetworkInterfaceTypeID
);
612 __kSCNetworkInterfaceIPv4
.interface_type
= kSCNetworkInterfaceTypeIPv4
;
613 __kSCNetworkInterfaceIPv4
.localized_key
= CFSTR("ipv4");
615 // get CFBundleRef for SystemConfiguration.framework
616 bundle
= _SC_CFBundleGet();
618 // get mach port used to communication with IOKit
619 kr
= IOMasterPort(MACH_PORT_NULL
, &masterPort
);
620 if (kr
!= KERN_SUCCESS
) {
621 SCLog(TRUE
, LOG_DEBUG
,
622 CFSTR("__SCNetworkInterfaceInitialize(), could not get IOMasterPort, kr = 0x%x"),
631 SCNetworkInterfacePrivateRef
632 __SCNetworkInterfaceCreatePrivate(CFAllocatorRef allocator
,
633 SCNetworkInterfaceRef interface
,
634 SCPreferencesRef prefs
,
635 CFStringRef serviceID
,
638 SCNetworkInterfacePrivateRef interfacePrivate
;
641 /* initialize runtime */
642 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
644 /* allocate target */
645 size
= sizeof(SCNetworkInterfacePrivate
) - sizeof(CFRuntimeBase
);
646 interfacePrivate
= (SCNetworkInterfacePrivateRef
)_CFRuntimeCreateInstance(allocator
,
647 __kSCNetworkInterfaceTypeID
,
650 if (interfacePrivate
== NULL
) {
654 interfacePrivate
->interface_type
= NULL
;
655 interfacePrivate
->name
= NULL
;
656 interfacePrivate
->localized_name
= NULL
;
657 interfacePrivate
->localized_key
= NULL
;
658 interfacePrivate
->localized_arg1
= NULL
;
659 interfacePrivate
->localized_arg2
= NULL
;
660 interfacePrivate
->interface
= (interface
!= NULL
) ? CFRetain(interface
) : NULL
;
661 interfacePrivate
->prefs
= (prefs
!= NULL
) ? CFRetain(prefs
) : NULL
;
662 interfacePrivate
->serviceID
= (serviceID
!= NULL
) ? CFRetain(serviceID
) : NULL
;
663 interfacePrivate
->unsaved
= NULL
;
664 interfacePrivate
->entity_device
= NULL
;
665 interfacePrivate
->entity_device_unique
= NULL
;
666 interfacePrivate
->entity_type
= NULL
;
667 interfacePrivate
->entity_subtype
= NULL
;
668 interfacePrivate
->supported_interface_types
= NULL
;
669 interfacePrivate
->supported_protocol_types
= NULL
;
670 interfacePrivate
->address
= NULL
;
671 interfacePrivate
->addressString
= NULL
;
672 interfacePrivate
->builtin
= FALSE
;
673 interfacePrivate
->configurationAction
= NULL
;
674 interfacePrivate
->path
= (path
!= NULL
) ? CFStringCreateWithCString(NULL
, path
, kCFStringEncodingUTF8
)
676 interfacePrivate
->location
= NULL
;
677 interfacePrivate
->overrides
= NULL
;
678 interfacePrivate
->modemIsV92
= FALSE
;
679 interfacePrivate
->type
= NULL
;
680 interfacePrivate
->unit
= NULL
;
681 interfacePrivate
->usb
.name
= NULL
;
682 interfacePrivate
->usb
.vid
= NULL
;
683 interfacePrivate
->usb
.pid
= NULL
;
684 interfacePrivate
->sort_order
= kSortUnknown
;
685 #if !TARGET_OS_IPHONE
686 interfacePrivate
->supportsBond
= FALSE
;
687 interfacePrivate
->bond
.interfaces
= NULL
;
688 interfacePrivate
->bond
.mode
= NULL
;
689 interfacePrivate
->bond
.options
= NULL
;
690 interfacePrivate
->supportsVLAN
= FALSE
;
691 interfacePrivate
->vlan
.interface
= NULL
;
692 interfacePrivate
->vlan
.tag
= NULL
;
693 interfacePrivate
->vlan
.options
= NULL
;
694 #endif // !TARGET_OS_IPHONE
696 return interfacePrivate
;
700 #if !TARGET_OS_IPHONE
703 __SCNetworkInterfaceSupportsVLAN(CFStringRef bsd_if
)
707 struct if_msghdr
* ifm
;
708 char * if_name
= NULL
;
709 unsigned int if_index
;
711 Boolean vlanOK
= FALSE
;
713 // get the interface index
714 if_name
= _SC_cfstring_to_cstring(bsd_if
, NULL
, 0, kCFStringEncodingASCII
);
715 if (if_name
== NULL
) {
716 return FALSE
; // if conversion error
718 if_index
= if_nametoindex(if_name
);
720 goto done
; // if unknown interface
723 // get information for the specified interface
728 mib
[4] = NET_RT_IFLIST
;
729 mib
[5] = if_index
; /* ask for exactly one interface */
731 if (sysctl(mib
, 6, NULL
, &buf_len
, NULL
, 0) == -1) {
732 SCLog(TRUE
, LOG_ERR
, CFSTR("sysctl() size failed: %s"), strerror(errno
));
735 buf
= CFAllocatorAllocate(NULL
, buf_len
, 0);
736 if (sysctl(mib
, 6, buf
, &buf_len
, NULL
, 0) == -1) {
737 SCLog(TRUE
, LOG_ERR
, CFSTR("sysctl() failed: %s"), strerror(errno
));
741 // check the link type and hwassist flags
742 ifm
= (struct if_msghdr
*)buf
;
743 switch (ifm
->ifm_type
) {
745 #if defined(IF_HWASSIST_VLAN_TAGGING) && defined(IF_HWASSIST_VLAN_MTU)
746 struct if_data
*if_data
= &ifm
->ifm_data
;
748 if (if_data
->ifi_hwassist
& (IF_HWASSIST_VLAN_TAGGING
| IF_HWASSIST_VLAN_MTU
)) {
758 if (if_name
!= NULL
) CFAllocatorDeallocate(NULL
, if_name
);
759 if (buf
!= NULL
) CFAllocatorDeallocate(NULL
, buf
);
766 SCNetworkInterfacePrivateRef
767 _SCBondInterfaceCreatePrivate(CFAllocatorRef allocator
,
770 SCNetworkInterfacePrivateRef interfacePrivate
;
772 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
, NULL
);
773 if (interfacePrivate
== NULL
) {
777 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBond
;
778 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
779 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, bond_if
);
780 interfacePrivate
->builtin
= TRUE
;
781 interfacePrivate
->supportsVLAN
= __SCNetworkInterfaceSupportsVLAN(bond_if
);
782 interfacePrivate
->sort_order
= kSortBond
;
784 interfacePrivate
->localized_key
= CFSTR("bond");
785 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
787 interfacePrivate
->bond
.interfaces
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
788 // interfacePrivate->bond.mode = NULL;
789 // interfacePrivate->bond.options = NULL;
791 return interfacePrivate
;
796 SCNetworkInterfacePrivateRef
797 _SCVLANInterfaceCreatePrivate(CFAllocatorRef allocator
,
800 SCNetworkInterfacePrivateRef interfacePrivate
;
802 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
, NULL
);
803 if (interfacePrivate
== NULL
) {
807 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeVLAN
;
808 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
809 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, vlan_if
);
810 interfacePrivate
->builtin
= TRUE
;
811 interfacePrivate
->sort_order
= kSortVLAN
;
813 interfacePrivate
->localized_key
= CFSTR("vlan");
814 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
816 // interfacePrivate->vlan.interface = NULL;
817 // interfacePrivate->vlan.tag = NULL;
818 // interfacePrivate->vlan.options = NULL;
820 return interfacePrivate
;
822 #endif // !TARGET_OS_IPHONE
826 #pragma mark Interface ordering
830 split_path(CFStringRef path
)
832 CFArrayRef components
;
833 CFMutableStringRef nPath
;
835 // turn '@'s into '/'s
836 nPath
= CFStringCreateMutableCopy(NULL
, 0, path
);
837 (void) CFStringFindAndReplace(nPath
,
840 CFRangeMake(0, CFStringGetLength(nPath
)),
843 // split path into components to be compared
844 components
= CFStringCreateArrayBySeparatingStrings(NULL
, nPath
, CFSTR("/"));
852 _SCNetworkInterfaceCompare(const void *val1
, const void *val2
, void *context
)
854 SCNetworkInterfacePrivateRef dev1
= (SCNetworkInterfacePrivateRef
)val1
;
855 SCNetworkInterfacePrivateRef dev2
= (SCNetworkInterfacePrivateRef
)val2
;
856 CFComparisonResult res
= kCFCompareEqualTo
;
858 /* sort by interface type */
859 if (dev1
->sort_order
!= dev2
->sort_order
) {
860 if (dev1
->sort_order
< dev2
->sort_order
) {
861 res
= kCFCompareLessThan
;
863 res
= kCFCompareGreaterThan
;
868 /* built-in interfaces sort first */
869 if (dev1
->builtin
!= dev2
->builtin
) {
871 res
= kCFCompareLessThan
;
873 res
= kCFCompareGreaterThan
;
878 /* ... and then, sort built-in interfaces by "location" */
880 if (dev1
->location
!= dev2
->location
) {
881 if (isA_CFString(dev1
->location
)) {
882 if (isA_CFString(dev2
->location
)) {
883 res
= CFStringCompare(dev1
->location
, dev2
->location
, 0);
885 res
= kCFCompareLessThan
;
888 res
= kCFCompareGreaterThan
;
891 if (res
!= kCFCompareEqualTo
) {
897 /* ... and, then sort by IOPathMatch */
898 if ((dev1
->path
!= NULL
) && (dev2
->path
!= NULL
)) {
899 CFArrayRef elements1
;
900 CFArrayRef elements2
;
906 elements1
= split_path(dev1
->path
);
907 n1
= CFArrayGetCount(elements1
);
909 elements2
= split_path(dev2
->path
);
910 n2
= CFArrayGetCount(elements2
);
912 n
= (n1
<= n2
) ? n1
: n2
;
913 for (i
= 0; i
< n
; i
++) {
922 e1
= CFArrayGetValueAtIndex(elements1
, i
);
923 e2
= CFArrayGetValueAtIndex(elements2
, i
);
925 str
= _SC_cfstring_to_cstring(e1
, NULL
, 0, kCFStringEncodingUTF8
);
927 q1
= strtoq(str
, &end
, 16);
928 isNum
= ((*str
!= '\0') && (*end
== '\0') && (errno
== 0));
929 CFAllocatorDeallocate(NULL
, str
);
932 // if e1 is a valid numeric string
933 str
= _SC_cfstring_to_cstring(e2
, NULL
, 0, kCFStringEncodingUTF8
);
935 q2
= strtoq(str
, &end
, 16);
936 isNum
= ((*str
!= '\0') && (*end
== '\0') && (errno
== 0));
937 CFAllocatorDeallocate(NULL
, str
);
940 // if e2 is also a valid numeric string
943 res
= kCFCompareEqualTo
;
945 } else if (q1
< q2
) {
946 res
= kCFCompareLessThan
;
948 res
= kCFCompareGreaterThan
;
954 res
= CFStringCompare(e1
, e2
, 0);
955 if (res
!= kCFCompareEqualTo
) {
960 if (res
== kCFCompareEqualTo
) {
962 res
= kCFCompareLessThan
;
963 } else if (n1
< n2
) {
964 res
= kCFCompareGreaterThan
;
968 CFRelease(elements1
);
969 CFRelease(elements2
);
971 if (res
!= kCFCompareEqualTo
) {
976 /* ... and, then sort by BSD interface name */
977 if ((dev1
->entity_device
!= NULL
) && (dev2
->entity_device
!= NULL
)) {
978 res
= CFStringCompare(dev1
->entity_device
, dev2
->entity_device
, 0);
979 if (res
!= kCFCompareEqualTo
) {
984 /* ... and lastly, sort by BSD interface unique identifier */
985 if ((dev1
->entity_device_unique
!= NULL
) && (dev2
->entity_device_unique
!= NULL
)) {
986 res
= CFStringCompare(dev1
->entity_device_unique
, dev2
->entity_device_unique
, 0);
987 // if (res != kCFCompareEqualTo) {
997 sort_interfaces(CFMutableArrayRef all_interfaces
)
999 int n
= CFArrayGetCount(all_interfaces
);
1005 CFArraySortValues(all_interfaces
, CFRangeMake(0, n
), _SCNetworkInterfaceCompare
, NULL
);
1012 __SCNetworkInterfaceOrder(SCNetworkInterfaceRef interface
)
1014 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
1016 return interfacePrivate
->sort_order
;
1021 #pragma mark Interface details
1025 IOCopyCFStringValue(CFTypeRef ioVal
)
1027 if (isA_CFString(ioVal
)) {
1028 return CFStringCreateCopy(NULL
, ioVal
);
1031 if (isA_CFData(ioVal
)) {
1032 return CFStringCreateWithCString(NULL
,
1033 (const char *)CFDataGetBytePtr(ioVal
),
1034 kCFStringEncodingUTF8
);
1042 IODictionaryCopyCFStringValue(CFDictionaryRef io_dict
, CFStringRef io_key
)
1046 ioVal
= CFDictionaryGetValue(io_dict
, io_key
);
1047 return IOCopyCFStringValue(ioVal
);
1052 IOStringValueHasPrefix(CFTypeRef ioVal
, CFStringRef prefix
)
1054 Boolean match
= FALSE
;
1055 CFIndex prefixLen
= CFStringGetLength(prefix
);
1056 CFStringRef str
= NULL
;
1058 if (!isA_CFString(ioVal
)) {
1059 if (isA_CFData(ioVal
)) {
1060 str
= CFStringCreateWithCStringNoCopy(NULL
,
1061 (const char *)CFDataGetBytePtr(ioVal
),
1062 kCFStringEncodingUTF8
,
1070 if ((ioVal
!= NULL
) &&
1071 (CFStringGetLength(ioVal
) >= prefixLen
) &&
1072 (CFStringCompareWithOptions(ioVal
,
1074 CFRangeMake(0, prefixLen
),
1075 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
)) {
1079 if (str
!= NULL
) CFRelease(str
);
1084 static const struct {
1085 const CFStringRef name
;
1086 const CFStringRef slot
;
1087 } slot_mappings
[] = {
1089 { CFSTR("A1") , CFSTR("1") },
1090 { CFSTR("B1") , CFSTR("2") },
1091 { CFSTR("C1") , CFSTR("3") },
1093 // Blue&White G3, Yikes G4
1094 { CFSTR("J12"), CFSTR("1") },
1095 { CFSTR("J11"), CFSTR("2") },
1096 { CFSTR("J10"), CFSTR("3") },
1097 { CFSTR("J9"), CFSTR("4") },
1100 { CFSTR("A") , CFSTR("1") },
1101 { CFSTR("B") , CFSTR("2") },
1102 { CFSTR("C") , CFSTR("3") },
1103 { CFSTR("D") , CFSTR("4") },
1105 // Digital Audio G4 (and later models)
1106 { CFSTR("1") , CFSTR("1") },
1107 { CFSTR("2") , CFSTR("2") },
1108 { CFSTR("3") , CFSTR("3") },
1109 { CFSTR("4") , CFSTR("4") },
1110 { CFSTR("5") , CFSTR("5") }
1115 pci_slot(io_registry_entry_t interface
, CFTypeRef
*pci_slot_name
)
1118 io_registry_entry_t parent
;
1119 CFMutableStringRef slot
;
1120 CFTypeRef slot_name
;
1123 if (pci_slot_name
!= NULL
) *pci_slot_name
= NULL
;
1125 slot_name
= IORegistryEntryCreateCFProperty(interface
, CFSTR("AAPL,slot-name"), NULL
, 0);
1126 if (slot_name
!= NULL
) {
1129 slot
= CFStringCreateMutable(NULL
, 0);
1130 if (isA_CFString(slot_name
)) {
1131 if (pci_slot_name
!= NULL
) *pci_slot_name
= CFStringCreateCopy(NULL
, slot_name
);
1132 CFStringAppend(slot
, slot_name
);
1133 } else if (isA_CFData(slot_name
)) {
1134 if (pci_slot_name
!= NULL
) *pci_slot_name
= CFDataCreateCopy(NULL
, slot_name
);
1135 CFStringAppendCString(slot
,
1136 (const char *)CFDataGetBytePtr(slot_name
),
1137 kCFStringEncodingUTF8
);
1140 if (CFStringGetLength(slot
) > 5) {
1141 (void) CFStringFindAndReplace(slot
,
1145 kCFCompareCaseInsensitive
|kCFCompareAnchored
);
1148 for (i
= 0; i
< sizeof(slot_mappings
)/sizeof(slot_mappings
[0]); i
++) {
1149 if (CFStringCompare(slot
,
1150 slot_mappings
[i
].name
,
1151 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
1153 slot
= (CFMutableStringRef
)CFRetain(slot_mappings
[i
].slot
);
1158 CFRelease(slot_name
);
1161 kr
= IORegistryEntryGetParentEntry(interface
, kIOServicePlane
, &parent
);
1163 case kIOReturnSuccess
: {
1164 CFTypeRef parent_pci_slot_name
= NULL
;
1165 CFStringRef parent_slot
;
1167 parent_slot
= pci_slot(parent
, &parent_pci_slot_name
);
1168 if (parent_slot
!= NULL
) {
1169 if (slot
!= NULL
) CFRelease(slot
);
1170 slot
= (CFMutableStringRef
)parent_slot
;
1172 if (pci_slot_name
!= NULL
) {
1173 if (*pci_slot_name
!= NULL
) CFRelease(*pci_slot_name
);
1174 *pci_slot_name
= parent_pci_slot_name
;
1176 CFRelease(parent_pci_slot_name
);
1180 IOObjectRelease(parent
);
1183 case kIOReturnNoDevice
:
1184 // if we have hit the root node
1187 SCLog(TRUE
, LOG_DEBUG
, CFSTR("pci_slot IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr
);
1195 static CFComparisonResult
1196 compare_bsdNames(const void *val1
, const void *val2
, void *context
)
1198 CFStringRef bsd1
= (CFStringRef
)val1
;
1199 CFStringRef bsd2
= (CFStringRef
)val2
;
1201 return CFStringCompare(bsd1
, bsd2
, 0);
1206 pci_port(CFTypeRef slot_name
, CFStringRef bsdName
)
1209 CFStringRef port_name
= NULL
;
1210 CFMutableArrayRef port_names
;
1213 CFStringRef match_keys
[2];
1214 CFTypeRef match_vals
[2];
1215 CFDictionaryRef match_dict
;
1216 CFDictionaryRef matching
;
1217 io_registry_entry_t slot
;
1218 io_iterator_t slot_iterator
= MACH_PORT_NULL
;
1220 match_keys
[0] = CFSTR("AAPL,slot-name");
1221 match_vals
[0] = slot_name
;
1223 match_dict
= CFDictionaryCreate(NULL
,
1224 (const void **)match_keys
,
1225 (const void **)match_vals
,
1227 &kCFTypeDictionaryKeyCallBacks
,
1228 &kCFTypeDictionaryValueCallBacks
);
1230 match_keys
[0] = CFSTR(kIOProviderClassKey
);
1231 match_vals
[0] = CFSTR("IOPCIDevice");
1233 match_keys
[1] = CFSTR(kIOPropertyMatchKey
);
1234 match_vals
[1] = match_dict
;
1236 // note: the "matching" dictionary will be consumed by the following
1237 matching
= CFDictionaryCreate(NULL
,
1238 (const void **)match_keys
,
1239 (const void **)match_vals
,
1240 sizeof(match_keys
)/sizeof(match_keys
[0]),
1241 &kCFTypeDictionaryKeyCallBacks
,
1242 &kCFTypeDictionaryValueCallBacks
);
1243 CFRelease(match_dict
);
1245 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &slot_iterator
);
1246 if (kr
!= kIOReturnSuccess
) {
1247 SCLog(TRUE
, LOG_DEBUG
, CFSTR("pci_port IOServiceGetMatchingServices() failed, kr = 0x%x"), kr
);
1248 return MACH_PORT_NULL
;
1251 port_names
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1253 while ((slot
= IOIteratorNext(slot_iterator
)) != MACH_PORT_NULL
) {
1254 io_registry_entry_t child
;
1255 io_iterator_t child_iterator
= MACH_PORT_NULL
;
1257 kr
= IORegistryEntryCreateIterator(slot
,
1259 kIORegistryIterateRecursively
,
1261 if (kr
!= kIOReturnSuccess
) {
1262 SCLog(TRUE
, LOG_DEBUG
, CFSTR("pci_port IORegistryEntryCreateIterator() failed, kr = 0x%x"), kr
);
1263 CFRelease(port_names
);
1264 return MACH_PORT_NULL
;
1267 while ((child
= IOIteratorNext(child_iterator
)) != MACH_PORT_NULL
) {
1268 if (IOObjectConformsTo(child
, kIONetworkInterfaceClass
)) {
1269 CFStringRef if_bsdName
;
1271 if_bsdName
= IORegistryEntryCreateCFProperty(child
,
1272 CFSTR(kIOBSDNameKey
),
1275 if (if_bsdName
!= NULL
) {
1276 CFArrayAppendValue(port_names
, if_bsdName
);
1277 CFRelease(if_bsdName
);
1280 IOObjectRelease(child
);
1282 IOObjectRelease(child_iterator
);
1283 IOObjectRelease(slot
);
1285 IOObjectRelease(slot_iterator
);
1287 n
= CFArrayGetCount(port_names
);
1289 CFArraySortValues(port_names
, CFRangeMake(0, n
), compare_bsdNames
, NULL
);
1290 n
= CFArrayGetFirstIndexOfValue(port_names
, CFRangeMake(0, n
), bsdName
);
1291 if (n
!= kCFNotFound
) {
1292 port_name
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%d"), n
+ 1);
1296 CFRelease(port_names
);
1302 pci_slot_info(io_registry_entry_t interface
, CFStringRef
*slot_name
, CFStringRef
*port_name
)
1304 CFStringRef bsd_name
;
1306 CFTypeRef pci_slot_name
;
1311 bsd_name
= IORegistryEntryCreateCFProperty(interface
, CFSTR(kIOBSDNameKey
), NULL
, 0);
1312 if (bsd_name
== NULL
) {
1316 *slot_name
= pci_slot(interface
, &pci_slot_name
);
1317 if (*slot_name
!= NULL
) {
1318 if (pci_slot_name
!= NULL
) {
1319 *port_name
= pci_port(pci_slot_name
, bsd_name
);
1320 CFRelease(pci_slot_name
);
1325 CFRelease(bsd_name
);
1331 isBuiltin(io_registry_entry_t interface
)
1335 slot
= pci_slot(interface
, NULL
);
1337 // interfaces which have a "slot" are not built-in
1347 isBluetoothBuiltin(Boolean
*haveController
)
1349 Boolean builtin
= FALSE
;
1350 io_object_t hciController
;
1351 io_iterator_t iter
= MACH_PORT_NULL
;
1354 kr
= IOServiceGetMatchingServices(masterPort
,
1355 IOServiceMatching("IOBluetoothHCIController"),
1357 if ((kr
!= kIOReturnSuccess
) || (iter
== MACH_PORT_NULL
)) {
1358 if (kr
!= kIOReturnSuccess
) {
1359 SCLog(TRUE
, LOG_DEBUG
, CFSTR("isBluetoothBuiltin IOServiceGetMatchingServices() failed, kr = 0x%x"), kr
);
1361 *haveController
= FALSE
;
1364 *haveController
= TRUE
;
1366 hciController
= IOIteratorNext(iter
);
1367 IOObjectRelease(iter
);
1368 if(hciController
!= MACH_PORT_NULL
) {
1369 CFNumberRef idVendor
;
1371 idVendor
= IORegistryEntryCreateCFProperty(hciController
, CFSTR(kUSBVendorID
), NULL
, 0);
1372 if (idVendor
!= NULL
) {
1375 if (isA_CFNumber(idVendor
) &&
1376 CFNumberGetValue(idVendor
, kCFNumberIntType
, &idVendorVal
) &&
1377 (idVendorVal
== kIOUSBVendorIDAppleComputer
)) {
1381 CFRelease(idVendor
);
1384 IOObjectRelease(hciController
);
1392 processUSBInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1393 io_registry_entry_t interface
,
1394 CFDictionaryRef interface_dict
,
1395 io_registry_entry_t controller
,
1396 CFDictionaryRef controller_dict
,
1397 io_registry_entry_t bus
,
1398 CFDictionaryRef bus_dict
)
1401 interfacePrivate
->usb
.name
= IORegistryEntrySearchCFProperty(interface
,
1403 CFSTR(kUSBProductString
),
1405 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1406 interfacePrivate
->usb
.vid
= IORegistryEntrySearchCFProperty(interface
,
1408 CFSTR(kUSBVendorID
),
1410 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1411 interfacePrivate
->usb
.pid
= IORegistryEntrySearchCFProperty(interface
,
1413 CFSTR(kUSBProductID
),
1415 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1422 #pragma mark Interface enumeration
1425 typedef Boolean (*processInterface
)(SCNetworkInterfacePrivateRef interfacePrivate
,
1426 io_registry_entry_t interface
,
1427 CFDictionaryRef interface_dict
,
1428 io_registry_entry_t controller
,
1429 CFDictionaryRef controller_dict
,
1430 io_registry_entry_t bus
,
1431 CFDictionaryRef bus_dict
);
1435 processNetworkInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1436 io_registry_entry_t interface
,
1437 CFDictionaryRef interface_dict
,
1438 io_registry_entry_t controller
,
1439 CFDictionaryRef controller_dict
,
1440 io_registry_entry_t bus
,
1441 CFDictionaryRef bus_dict
)
1451 num
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceType
));
1452 if (isA_CFNumber(num
) &&
1453 CFNumberGetValue(num
, kCFNumberIntType
, &ift
)) {
1454 interfacePrivate
->type
= CFRetain(num
);
1456 SCLog(TRUE
, LOG_DEBUG
, CFSTR("processNetworkInterface() failed, no interface type"));
1464 if ((IOObjectConformsTo(controller
, "IO80211Controller")) ||
1465 (IOObjectConformsTo(controller
, "AirPortPCI" )) ||
1466 (IOObjectConformsTo(controller
, "AirPortDriver" ))) {
1467 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
1468 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1469 interfacePrivate
->sort_order
= kSortAirPort
;
1470 } else if (IOObjectConformsTo(controller
, "IOBluetoothBNEPDriver")) {
1471 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1472 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1473 interfacePrivate
->sort_order
= kSortBluetoothPAN
;
1474 } else if (IOObjectConformsTo(controller
, "AppleUSBEthernetHost")) {
1475 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1476 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1477 interfacePrivate
->sort_order
= kSortTethered
;
1478 } else if (IOObjectConformsTo(controller
, "AppleUSBCDCECMData")) {
1479 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1480 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1481 interfacePrivate
->sort_order
= kSortWWANEthernet
;
1483 str
= IODictionaryCopyCFStringValue(bus_dict
, CFSTR("name"));
1484 if ((str
!= NULL
) && CFEqual(str
, CFSTR("radio"))) {
1485 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
; // ??
1486 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1487 interfacePrivate
->sort_order
= kSortOtherWireless
;
1489 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1490 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1491 interfacePrivate
->sort_order
= kSortEthernet
;
1493 #if !TARGET_OS_IPHONE
1494 // BOND support only enabled for ethernet devices
1495 interfacePrivate
->supportsBond
= TRUE
;
1496 #endif // !TARGET_OS_IPHONE
1499 if (str
!= NULL
) CFRelease(str
);
1503 val
= isA_CFBoolean(CFDictionaryGetValue(interface_dict
, CFSTR(kIOBuiltin
)));
1505 val
= isA_CFBoolean(CFDictionaryGetValue(interface_dict
, CFSTR(kIOPrimaryInterface
)));
1508 interfacePrivate
->builtin
= CFBooleanGetValue(val
);
1510 interfacePrivate
->builtin
= isBuiltin(interface
);
1513 if (!interfacePrivate
->builtin
&&
1514 CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
)) {
1515 // always treat AirPort interfaces as built-in
1516 interfacePrivate
->builtin
= TRUE
;
1520 interfacePrivate
->location
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOLocation
));
1522 #if !TARGET_OS_IPHONE
1524 num
= CFDictionaryGetValue(controller_dict
, CFSTR(kIOFeatures
));
1525 if (isA_CFNumber(num
) &&
1526 CFNumberGetValue(num
, kCFNumberIntType
, & iVal
)) {
1527 if (iVal
& (kIONetworkFeatureHardwareVlan
| kIONetworkFeatureSoftwareVlan
)) {
1528 interfacePrivate
->supportsVLAN
= TRUE
;
1531 #endif // !TARGET_OS_IPHONE
1534 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
)) {
1535 interfacePrivate
->localized_key
= CFSTR("airport");
1536 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN
) {
1537 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan");
1538 } else if (interfacePrivate
->sort_order
== kSortOtherWireless
) {
1539 interfacePrivate
->localized_key
= CFSTR("wireless");
1540 interfacePrivate
->localized_arg1
= CFRetain(CFSTR("")); // ??
1541 } else if (interfacePrivate
->builtin
) {
1542 if ((interfacePrivate
->location
== NULL
) ||
1543 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1544 interfacePrivate
->localized_key
= CFSTR("ether");
1546 interfacePrivate
->localized_key
= CFSTR("multiether");
1547 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->location
);
1550 CFStringRef provider
;
1552 // check provider class
1553 provider
= IORegistryEntrySearchCFProperty(interface
,
1555 CFSTR(kIOProviderClassKey
),
1557 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1558 if (provider
!= NULL
) {
1559 if (CFEqual(provider
, CFSTR("IOPCIDevice"))) {
1560 CFStringRef port_name
;
1561 CFStringRef slot_name
;
1563 if (pci_slot_info(interface
, &slot_name
, &port_name
)) {
1564 if (port_name
== NULL
) {
1565 interfacePrivate
->localized_key
= CFSTR("pci-ether");
1566 interfacePrivate
->localized_arg1
= slot_name
;
1568 interfacePrivate
->localized_key
= CFSTR("pci-multiether");
1569 interfacePrivate
->localized_arg1
= slot_name
;
1570 interfacePrivate
->localized_arg2
= port_name
;
1573 } else if (CFEqual(provider
, CFSTR("IOUSBDevice")) ||
1574 CFEqual(provider
, CFSTR("IOUSBInterface"))) {
1576 processUSBInterface(interfacePrivate
,
1584 // check if a "Product Name" has been provided
1585 val
= IORegistryEntrySearchCFProperty(interface
,
1587 CFSTR(kIOPropertyProductNameKey
),
1589 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1590 if ((val
== NULL
) && (interfacePrivate
->usb
.name
!= NULL
)) {
1591 // else, use "USB Product Name" if available
1592 val
= CFRetain(interfacePrivate
->usb
.name
);
1595 CFStringRef productName
;
1597 productName
= IOCopyCFStringValue(val
);
1600 if (productName
!= NULL
) {
1601 if (CFStringGetLength(productName
) > 0) {
1602 // if we have a [somewhat reasonable?] product name
1603 if (interfacePrivate
->name
!= NULL
) {
1604 CFRelease(interfacePrivate
->name
);
1606 interfacePrivate
->name
= CFRetain(productName
);
1607 if (interfacePrivate
->localized_name
!= NULL
) {
1608 CFRelease(interfacePrivate
->localized_name
);
1610 interfacePrivate
->localized_name
= copy_interface_string(bundle
, productName
, TRUE
);
1613 CFRelease(productName
);
1616 interfacePrivate
->localized_key
= CFSTR("usb-ether");
1617 interfacePrivate
->localized_arg1
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOBSDNameKey
));
1620 CFRelease(provider
);
1623 if (interfacePrivate
->localized_key
== NULL
) {
1624 // if no provider, not a PCI device, or no slot information
1625 interfacePrivate
->localized_key
= CFSTR("generic-ether");
1626 interfacePrivate
->localized_arg1
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOBSDNameKey
));
1633 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeFireWire
;
1636 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeFireWire
;
1639 interfacePrivate
->builtin
= isBuiltin(interface
);
1642 interfacePrivate
->sort_order
= kSortFireWire
;
1645 if (interfacePrivate
->builtin
) {
1646 interfacePrivate
->localized_key
= CFSTR("firewire");
1648 CFStringRef slot_name
;
1650 slot_name
= pci_slot(interface
, NULL
);
1651 if (slot_name
!= NULL
) {
1652 interfacePrivate
->localized_key
= CFSTR("pci-firewire");
1653 interfacePrivate
->localized_arg1
= slot_name
;
1659 SCLog(TRUE
, LOG_DEBUG
, CFSTR("processNetworkInterface() failed, unknown interface type = %d"), ift
);
1664 interfacePrivate
->entity_device
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOBSDNameKey
));
1666 // Hardware (MAC) address
1667 data
= CFDictionaryGetValue(controller_dict
, CFSTR(kIOMACAddress
));
1668 if (isA_CFData(data
)) {
1669 interfacePrivate
->address
= CFRetain(data
);
1673 num
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceUnit
));
1674 if (isA_CFNumber(num
) &&
1675 CFNumberGetValue(num
, kCFNumberIntType
, & iVal
)) {
1676 interfacePrivate
->unit
= CFRetain(num
);
1684 set_connection_script(SCNetworkInterfacePrivateRef interfacePrivate
, CFStringRef script
)
1686 CFDictionaryRef dict
;
1687 CFMutableDictionaryRef newDict
;
1689 if (interfacePrivate
->overrides
== NULL
) {
1690 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
1692 &kCFTypeDictionaryKeyCallBacks
,
1693 &kCFTypeDictionaryValueCallBacks
);
1696 dict
= CFDictionaryGetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
1698 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
1700 newDict
= CFDictionaryCreateMutable(NULL
,
1702 &kCFTypeDictionaryKeyCallBacks
,
1703 &kCFTypeDictionaryValueCallBacks
);
1705 if (script
!= NULL
) {
1706 CFDictionarySetValue(newDict
, kSCPropNetModemConnectionScript
, script
);
1708 CFDictionaryRemoveValue(newDict
, kSCPropNetModemConnectionScript
);
1710 if (CFDictionaryGetCount(newDict
) > 0) {
1711 CFDictionarySetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
, newDict
);
1713 CFDictionaryRemoveValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
1717 if (CFDictionaryGetCount(interfacePrivate
->overrides
) == 0) {
1718 CFRelease(interfacePrivate
->overrides
);
1719 interfacePrivate
->overrides
= NULL
;
1726 is_valid_connection_script(CFStringRef script
)
1728 char ccl
[MAXPATHLEN
];
1729 char path
[MAXPATHLEN
];
1730 NSSearchPathEnumerationState state
;
1732 (void) _SC_cfstring_to_cstring(script
,
1735 kCFStringEncodingUTF8
);
1737 state
= NSStartSearchPathEnumeration(NSLibraryDirectory
,
1738 NSLocalDomainMask
|NSSystemDomainMask
);
1739 while ((state
= NSGetNextSearchPathEnumeration(state
, path
))) {
1741 struct stat statBuf
;
1743 if (ccl
[0] == '/') {
1744 path
[0] = '\0'; // if modemCCL is a full path
1746 strlcat(path
, "/Modem Scripts/", sizeof(path
));
1748 strlcat(path
, ccl
, sizeof(path
));
1750 if (stat(path
, &statBuf
) != 0) {
1751 if (errno
== ENOENT
) {
1755 SCLog(TRUE
, LOG_DEBUG
,
1756 CFSTR("processSerialInterface stat() failed: %s"),
1760 if (S_ISREG(statBuf
.st_mode
)) {
1761 // if we have a valid CCL script
1765 #define BUNDLE_EXT ".ccl"
1766 #define BUNDLE_EXT_LEN sizeof(BUNDLE_EXT) - 1
1771 if ((n
<= BUNDLE_EXT_LEN
) ||
1772 (strstr(&path
[n
- BUNDLE_EXT_LEN
], BUNDLE_EXT
) == NULL
)) {
1773 strlcat(path
, BUNDLE_EXT
, sizeof(path
));
1774 if (stat(path
, &statBuf
) != 0) {
1775 if (errno
== ENOENT
) {
1779 SCLog(TRUE
, LOG_DEBUG
,
1780 CFSTR("processSerialInterface stat() failed: %s"),
1785 if (S_ISDIR(statBuf
.st_mode
)) {
1786 // if we have a valid CCL bundle
1796 processSerialInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1797 io_registry_entry_t interface
,
1798 CFDictionaryRef interface_dict
,
1799 io_registry_entry_t controller
,
1800 CFDictionaryRef controller_dict
,
1801 io_registry_entry_t bus
,
1802 CFDictionaryRef bus_dict
)
1804 CFStringRef base
= NULL
;
1806 Boolean isModem
= FALSE
;
1807 Boolean isWWAN
= FALSE
;
1808 CFStringRef modemCCL
= NULL
;
1813 val
= IORegistryEntrySearchCFProperty(interface
,
1815 CFSTR("HiddenPort"),
1817 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1820 return FALSE
; // if this interface should not be exposed
1823 // check if initializing
1824 val
= IORegistryEntrySearchCFProperty(interface
,
1826 CFSTR("Initializing"),
1828 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1830 Boolean initializing
;
1832 initializing
= isA_CFBoolean(val
) && CFBooleanGetValue(val
);
1835 return FALSE
; // if this interface is still initializing
1840 val
= IORegistryEntrySearchCFProperty(interface
,
1844 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1846 isWWAN
= isA_CFBoolean(val
) && CFBooleanGetValue(val
);
1851 interfacePrivate
->entity_device
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOTTYDeviceKey
));
1852 if (interfacePrivate
->entity_device
== NULL
) {
1856 base
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOTTYBaseNameKey
));
1858 base
= CFRetain(interfacePrivate
->entity_device
);
1864 * Exclude ports named "irda" because otherwise the IrDA ports on the
1865 * original iMac (rev's A through D) show up as serial ports. Given
1866 * that only the rev A actually had an IrDA port, and Mac OS X doesn't
1867 * even support it, these ports definitely shouldn't be listed.
1869 if (CFStringCompare(base
,
1871 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
1875 if (IOStringValueHasPrefix(base
, CFSTR("bluetooth"))) {
1876 Boolean haveController
= FALSE
;
1879 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBluetooth
;
1880 interfacePrivate
->sort_order
= kSortBluetooth
;
1881 interfacePrivate
->builtin
= isBluetoothBuiltin(&haveController
);
1882 if (!haveController
) {
1883 // if device with no controller present
1886 } else if (IOStringValueHasPrefix(base
, CFSTR("irda-ircomm"))) {
1888 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIrDA
;
1889 interfacePrivate
->sort_order
= kSortIrDA
;
1890 } else if (isWWAN
) {
1892 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeWWAN
;
1893 interfacePrivate
->sort_order
= kSortWWAN
;
1896 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeModem
;
1897 interfacePrivate
->sort_order
= kSortModem
;
1900 val
= IORegistryEntrySearchCFProperty(interface
,
1902 CFSTR(kIODeviceSupportsHoldKey
),
1904 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1908 if (isA_CFNumber(val
) &&
1909 CFNumberGetValue(val
, kCFNumberSInt32Type
, &v92
)) {
1910 interfacePrivate
->modemIsV92
= (v92
== 1);
1917 interfacePrivate
->entity_type
= kSCEntNetModem
;
1919 // Entity (Hardware)
1920 ift
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOSerialBSDTypeKey
));
1921 if (!isA_CFString(ift
)) {
1925 if (CFEqual(ift
, CFSTR(kIOSerialBSDModemType
))) {
1929 if (CFEqual(base
, CFSTR("modem"))) {
1930 interfacePrivate
->builtin
= TRUE
;
1931 interfacePrivate
->sort_order
= kSortInternalModem
;
1932 } else if (CFEqual(base
, CFSTR("usbmodem"))) {
1933 interfacePrivate
->sort_order
= kSortUSBModem
;
1935 } else if (CFEqual(ift
, CFSTR(kIOSerialBSDRS232Type
))) {
1937 interfacePrivate
->sort_order
= kSortSerialPort
;
1942 // configuration template overrides
1943 val
= IORegistryEntrySearchCFProperty(interface
,
1945 CFSTR("DevicePPPOverrides"),
1947 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1949 if (isA_CFDictionary(val
)) {
1950 if (interfacePrivate
->overrides
== NULL
) {
1951 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
1953 &kCFTypeDictionaryKeyCallBacks
,
1954 &kCFTypeDictionaryValueCallBacks
);
1956 CFDictionarySetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypePPP
, val
);
1961 val
= IORegistryEntrySearchCFProperty(interface
,
1963 CFSTR("DeviceModemOverrides"),
1965 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1967 if (isA_CFDictionary(val
)) {
1968 CFStringRef uniqueID
;
1970 if (interfacePrivate
->overrides
== NULL
) {
1971 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
1973 &kCFTypeDictionaryKeyCallBacks
,
1974 &kCFTypeDictionaryValueCallBacks
);
1976 CFDictionarySetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
, val
);
1978 modemCCL
= CFDictionaryGetValue(val
, kSCPropNetModemConnectionScript
);
1979 modemCCL
= isA_CFString(modemCCL
);
1981 uniqueID
= CFDictionaryGetValue(val
, CFSTR("UniqueIdentifier"));
1982 uniqueID
= isA_CFString(uniqueID
);
1983 if (uniqueID
!= NULL
) {
1984 // retain the device's base name and the unique id
1985 CFRelease(interfacePrivate
->entity_device
);
1986 interfacePrivate
->entity_device
= CFRetain(base
);
1987 interfacePrivate
->entity_device_unique
= CFStringCreateCopy(NULL
, uniqueID
);
1993 // if not part of the DeviceModemOverrides, look harder for the modem CCL
1994 if (modemCCL
== NULL
) {
1995 val
= IORegistryEntrySearchCFProperty(interface
,
1999 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2001 modemCCL
= IOCopyCFStringValue(val
);
2002 if (modemCCL
!= NULL
) {
2003 set_connection_script(interfacePrivate
, modemCCL
);
2004 CFRelease(modemCCL
);
2012 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIrDA
)) {
2013 interfacePrivate
->localized_key
= CFSTR("irda");
2014 } else if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBluetooth
)) {
2015 interfacePrivate
->localized_key
= CFSTR("bluetooth");
2017 CFStringRef localized
= NULL
;
2018 CFStringRef name
= NULL
;
2019 CFMutableStringRef port
;
2021 port
= CFStringCreateMutableCopy(NULL
, 0, base
);
2022 CFStringLowercase(port
, NULL
);
2025 CFStringAppend(port
, CFSTR("-port"));
2028 // set non-localized name
2029 if (bundle
!= NULL
) {
2030 name
= copy_interface_string(bundle
, port
, FALSE
);
2033 if (!CFEqual(port
, name
)) {
2034 // if [English] localization available
2035 interfacePrivate
->name
= name
;
2037 // if no [English] localization available, use TTY base name
2039 interfacePrivate
->name
= CFStringCreateCopy(NULL
, base
);
2042 interfacePrivate
->name
= CFStringCreateCopy(NULL
, base
);
2045 // set localized name
2046 if (bundle
!= NULL
) {
2047 localized
= copy_interface_string(bundle
, port
, TRUE
);
2049 if (localized
!= NULL
) {
2050 if (!CFEqual(port
, localized
)) {
2051 // if localization available
2052 interfacePrivate
->localized_name
= localized
;
2054 // if no localization available, use TTY base name
2055 CFRelease(localized
);
2056 interfacePrivate
->localized_name
= CFStringCreateCopy(NULL
, base
);
2059 interfacePrivate
->localized_name
= CFStringCreateCopy(NULL
, base
);
2062 if (!isModem
|| !CFEqual(base
, CFSTR("modem"))) {
2063 CFStringRef productName
;
2065 // check if a "Product Name" has been provided
2066 val
= IORegistryEntrySearchCFProperty(interface
,
2068 CFSTR(kIOPropertyProductNameKey
),
2070 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2072 // check if a "USB Product Name" has been provided
2073 val
= IORegistryEntrySearchCFProperty(interface
,
2075 CFSTR(kUSBProductString
),
2077 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2080 productName
= IOCopyCFStringValue(val
);
2083 if (productName
!= NULL
) {
2084 if (CFStringGetLength(productName
) > 0) {
2085 // if we have a [somewhat reasonable?] product name
2086 if (interfacePrivate
->name
!= NULL
) {
2087 CFRelease(interfacePrivate
->name
);
2089 interfacePrivate
->name
= CFRetain(productName
);
2090 if (interfacePrivate
->localized_name
!= NULL
) {
2091 CFRelease(interfacePrivate
->localized_name
);
2093 interfacePrivate
->localized_name
= copy_interface_string(bundle
, productName
, TRUE
);
2095 // if not provided, also check if the product name
2096 // matches a CCL script
2097 if ((modemCCL
== NULL
) &&
2098 is_valid_connection_script(productName
)) {
2099 set_connection_script(interfacePrivate
, productName
);
2103 CFRelease(productName
);
2115 if (!ok
&& (interfacePrivate
->entity_device
!= NULL
)) {
2116 CFRelease(interfacePrivate
->entity_device
);
2117 interfacePrivate
->entity_device
= NULL
;
2119 if (base
!= NULL
) CFRelease(base
);
2125 static SCNetworkInterfaceRef
2126 createInterface(io_registry_entry_t interface
, processInterface func
)
2128 io_registry_entry_t bus
= MACH_PORT_NULL
;
2129 CFMutableDictionaryRef bus_dict
= NULL
;
2130 io_registry_entry_t controller
= MACH_PORT_NULL
;
2131 CFMutableDictionaryRef controller_dict
= NULL
;
2132 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
2133 CFMutableDictionaryRef interface_dict
= NULL
;
2137 kr
= IORegistryEntryGetPath(interface
, kIOServicePlane
, path
);
2138 if (kr
!= kIOReturnSuccess
) {
2139 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryGetPath() failed, kr = 0x%x"), kr
);
2143 kr
= IORegistryEntryCreateCFProperties(interface
, &interface_dict
, NULL
, kNilOptions
);
2144 if (kr
!= kIOReturnSuccess
) {
2145 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryCreateCFProperties() failed, kr = 0x%x"), kr
);
2149 /* get the controller node */
2150 kr
= IORegistryEntryGetParentEntry(interface
, kIOServicePlane
, &controller
);
2151 if (kr
!= KERN_SUCCESS
) {
2152 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr
);
2156 /* get the dictionary associated with the node */
2157 kr
= IORegistryEntryCreateCFProperties(controller
, &controller_dict
, NULL
, kNilOptions
);
2158 if (kr
!= KERN_SUCCESS
) {
2159 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryCreateCFProperties() failed, kr = 0x%x"), kr
);
2163 /* get the bus node */
2164 kr
= IORegistryEntryGetParentEntry(controller
, kIOServicePlane
, &bus
);
2165 if (kr
!= KERN_SUCCESS
) {
2166 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr
);
2170 /* get the dictionary associated with the node */
2171 kr
= IORegistryEntryCreateCFProperties(bus
, &bus_dict
, NULL
, kNilOptions
);
2172 if (kr
!= KERN_SUCCESS
) {
2173 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryCreateCFProperties() failed, kr = 0x%x"), kr
);
2177 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
, path
);
2179 if ((*func
)(interfacePrivate
, interface
, interface_dict
, controller
, controller_dict
, bus
, bus_dict
)) {
2182 /* check user-notification / auto-configuration preferences */
2183 val
= IORegistryEntrySearchCFProperty(interface
,
2185 kSCNetworkInterfaceConfigurationActionKey
,
2187 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2189 if (isA_CFString(val
)) {
2190 interfacePrivate
->configurationAction
= CFRetain(val
);
2195 CFRelease(interfacePrivate
);
2196 interfacePrivate
= NULL
;
2201 if (interface_dict
!= NULL
) CFRelease(interface_dict
);
2203 if (controller
!= MACH_PORT_NULL
) IOObjectRelease(controller
);
2204 if (controller_dict
!= NULL
) CFRelease(controller_dict
);
2206 if (bus
!= MACH_PORT_NULL
) IOObjectRelease(bus
);
2207 if (bus_dict
!= NULL
) CFRelease(bus_dict
);
2209 return (SCNetworkInterfaceRef
)interfacePrivate
;
2214 findMatchingInterfaces(CFDictionaryRef matching
, processInterface func
)
2216 CFMutableArrayRef interfaces
;
2217 io_registry_entry_t interface
;
2219 io_iterator_t iterator
= MACH_PORT_NULL
;
2221 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &iterator
);
2222 if (kr
!= kIOReturnSuccess
) {
2223 SCLog(TRUE
, LOG_DEBUG
, CFSTR("findMatchingInterfaces IOServiceGetMatchingServices() failed, kr = 0x%x"), kr
);
2227 interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2229 while ((interface
= IOIteratorNext(iterator
)) != MACH_PORT_NULL
) {
2230 SCNetworkInterfaceRef match
;
2232 match
= createInterface(interface
, func
);
2233 if (match
!= NULL
) {
2234 CFArrayAppendValue(interfaces
, match
);
2238 IOObjectRelease(interface
);
2241 IOObjectRelease(iterator
);
2248 #pragma mark helper functions
2252 findConfiguration(CFStringRef interface_type
)
2256 for (i
= 0; i
< sizeof(configurations
)/sizeof(configurations
[0]); i
++) {
2257 if (CFEqual(interface_type
, *configurations
[i
].interface_type
)) {
2268 __SCNetworkInterfaceGetDefaultConfigurationType(SCNetworkInterfaceRef interface
)
2270 CFIndex interfaceIndex
;
2271 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2273 if (interfacePrivate
->serviceID
== NULL
) {
2274 // if not associated with a service (yet)
2275 _SCErrorSet(kSCStatusInvalidArgument
);
2279 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2280 if (interfaceIndex
== kCFNotFound
) {
2281 // unknown interface type, use per-service configuration preferences
2282 return interfacePrivate
->interface_type
; // entity
2285 if (configurations
[interfaceIndex
].entity_hardware
!= NULL
) {
2286 // if configuration information can be associated with this interface type
2287 return *configurations
[interfaceIndex
].entity_hardware
;
2290 _SCErrorSet(kSCStatusInvalidArgument
);
2297 __SCNetworkInterfaceIsValidExtendedConfigurationType(SCNetworkInterfaceRef interface
,
2298 CFStringRef extendedType
,
2299 Boolean requirePerInterface
)
2301 CFStringRef defaultType
;
2302 CFIndex extendedIndex
;
2303 CFIndex interfaceIndex
;
2304 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2305 Boolean isL2TP
= FALSE
;
2308 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
2309 if (defaultType
== NULL
) {
2313 if (CFEqual(extendedType
, defaultType
)) {
2314 // extended and default configuration types cannot conflict
2318 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2319 if (interfaceIndex
== kCFNotFound
) {
2320 // configuration information for unknown interface type's
2321 // are stored along with the service and we don't allow
2322 // per-service extended configurations
2326 if (CFEqual(extendedType
, kSCEntNetIPSec
)) {
2327 CFStringRef interfaceType
;
2329 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
2330 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
2331 SCNetworkInterfaceRef child
;
2333 child
= SCNetworkInterfaceGetInterface(interface
);
2334 if (child
!= NULL
) {
2335 interfaceType
= SCNetworkInterfaceGetInterfaceType(child
);
2336 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
2343 if (requirePerInterface
&&
2344 !configurations
[interfaceIndex
].per_interface_config
&&
2346 // we don't allow per-service extended configurations (except
2347 // that we do allow IPSec as an extended type for PPP->L2TP)
2351 extendedIndex
= findConfiguration(extendedType
);
2352 if ((extendedIndex
!= kCFNotFound
) && !isL2TP
) {
2353 // extended type cannot match a known interface type (except
2354 // that we do allow IPSec as an extended type for PPP->L2TP)
2360 * Do we match specific/known extended configuration types (e.g. EAPOL)
2361 * and ensure that any non-standard extended configuration types be of
2362 * the form com.myCompany.myType?
2371 _SCErrorSet(kSCStatusInvalidArgument
);
2378 CFStringRef defaultType
;
2379 CFMutableArrayRef types
;
2380 } extendedConfiguration
, *extendedConfigurationRef
;
2384 __addExtendedConfigurationType(const void *key
, const void *value
, void *context
)
2386 CFStringRef extendedType
= (CFStringRef
)key
;
2387 extendedConfigurationRef myContextRef
= (extendedConfigurationRef
)context
;
2389 if (CFEqual(extendedType
, myContextRef
->defaultType
)) {
2390 // do not include the default configuration type
2394 if (CFArrayContainsValue(myContextRef
->types
,
2395 CFRangeMake(0, CFArrayGetCount(myContextRef
->types
)),
2397 // if extendedType already has already been added
2401 CFArrayAppendValue(myContextRef
->types
, extendedType
);
2408 extendedConfigurationTypes(SCNetworkInterfaceRef interface
)
2411 CFIndex interfaceIndex
;
2412 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2413 extendedConfiguration myContext
;
2414 SCNetworkServiceRef service
;
2418 myContext
.defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
2419 if (myContext
.defaultType
== NULL
) {
2420 myContext
.types
= NULL
;
2424 myContext
.types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2426 if (interfacePrivate
->serviceID
== NULL
) {
2427 // if not associated with a service (yet)
2431 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2432 if (interfaceIndex
== kCFNotFound
) {
2433 // we don't allow per-service extended configurations
2437 if (!configurations
[interfaceIndex
].per_interface_config
) {
2438 // known interface type but we still don't allow
2439 // per-service extended configurations
2443 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
2444 interfacePrivate
->prefs
,
2445 interfacePrivate
->serviceID
,
2448 sets
= SCNetworkSetCopyAll(interfacePrivate
->prefs
);
2449 n
= (sets
!= NULL
) ? CFArrayGetCount(sets
) : 0;
2451 for (i
= 0; i
< n
; i
++) {
2452 CFDictionaryRef configs
;
2455 CFArrayRef services
;
2456 SCNetworkSetRef set
;
2458 set
= CFArrayGetValueAtIndex(sets
, i
);
2459 services
= SCNetworkSetCopyServices(set
);
2460 found
= CFArrayContainsValue(services
,
2461 CFRangeMake(0, CFArrayGetCount(services
)),
2463 CFRelease(services
);
2469 // add stored extended configuration types
2470 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
2471 SCNetworkSetGetSetID(set
), // set
2472 interfacePrivate
->entity_device
, // service
2474 configs
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
2476 if (isA_CFDictionary(configs
)) {
2477 CFDictionaryApplyFunction(configs
,
2478 __addExtendedConfigurationType
,
2482 // add not-yet-stored extended configuration types
2483 if (interfacePrivate
->unsaved
!= NULL
) {
2484 CFDictionaryApplyFunction(interfacePrivate
->unsaved
,
2485 __addExtendedConfigurationType
,
2493 if (sets
!= NULL
) CFRelease(sets
);
2497 return myContext
.types
;
2502 copyConfigurationPaths(SCNetworkInterfacePrivateRef interfacePrivate
,
2503 CFStringRef extendedType
)
2505 CFMutableArrayRef array
;
2507 CFIndex interfaceIndex
;
2510 SCNetworkServiceRef service
;
2513 array
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2515 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2516 if (interfaceIndex
== kCFNotFound
) {
2517 // unknown interface type, use per-service configuration preferences
2518 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
2519 interfacePrivate
->serviceID
, // service
2520 extendedType
); // entity
2521 CFArrayAppendValue(array
, path
);
2526 if (!configurations
[interfaceIndex
].per_interface_config
) {
2527 // known interface type, per-service configuration preferences
2528 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
2529 interfacePrivate
->serviceID
, // service
2530 extendedType
); // entity
2531 CFArrayAppendValue(array
, path
);
2536 // known interface type, per-interface configuration preferences
2538 // 1. look for all sets which contain the associated service
2539 // 2. add a per-set path for the interface configuration for
2542 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
2543 interfacePrivate
->prefs
,
2544 interfacePrivate
->serviceID
,
2545 (SCNetworkInterfaceRef
)interfacePrivate
);
2547 sets
= SCNetworkSetCopyAll(interfacePrivate
->prefs
);
2548 n
= (sets
!= NULL
) ? CFArrayGetCount(sets
) : 0;
2550 for (i
= 0; i
< n
; i
++) {
2551 CFArrayRef services
;
2552 SCNetworkSetRef set
;
2554 set
= CFArrayGetValueAtIndex(sets
, i
);
2555 services
= SCNetworkSetCopyServices(set
);
2556 if (CFArrayContainsValue(services
,
2557 CFRangeMake(0, CFArrayGetCount(services
)),
2559 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
2560 SCNetworkSetGetSetID(set
), // set
2561 interfacePrivate
->entity_device
, // service
2562 extendedType
); // entity
2563 CFArrayAppendValue(array
, path
);
2566 CFRelease(services
);
2569 if (CFArrayGetCount(array
) == 0) {
2575 if (sets
!= NULL
) CFRelease(sets
);
2581 #pragma mark SCNetworkInterface <--> preferences entity
2586 __SCNetworkInterfaceCopyInterfaceEntity(SCNetworkInterfaceRef interface
)
2588 CFMutableDictionaryRef entity
;
2589 CFIndex interfaceIndex
;
2590 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2592 entity
= CFDictionaryCreateMutable(NULL
,
2594 &kCFTypeDictionaryKeyCallBacks
,
2595 &kCFTypeDictionaryValueCallBacks
);
2596 if (interfacePrivate
->entity_type
!= NULL
) {
2597 CFDictionarySetValue(entity
,
2598 kSCPropNetInterfaceType
,
2599 interfacePrivate
->entity_type
);
2601 if (interfacePrivate
->entity_subtype
!= NULL
) {
2602 CFDictionarySetValue(entity
,
2603 kSCPropNetInterfaceSubType
,
2604 interfacePrivate
->entity_subtype
);
2606 if (interfacePrivate
->entity_device
!= NULL
) {
2607 CFDictionarySetValue(entity
,
2608 kSCPropNetInterfaceDeviceName
,
2609 interfacePrivate
->entity_device
);
2611 if (interfacePrivate
->entity_device_unique
!= NULL
) {
2612 CFDictionarySetValue(entity
,
2613 CFSTR("DeviceUniqueIdentifier"),
2614 interfacePrivate
->entity_device_unique
);
2617 // match the "hardware" with the lowest layer
2619 SCNetworkInterfaceRef nextInterface
;
2621 nextInterface
= SCNetworkInterfaceGetInterface(interface
);
2622 if (nextInterface
== NULL
) {
2626 interface
= nextInterface
;
2628 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2630 if (CFEqual(interface
, kSCNetworkInterfaceIPv4
)) {
2634 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2635 if (interfaceIndex
!= kCFNotFound
) {
2636 if (configurations
[interfaceIndex
].entity_hardware
!= NULL
) {
2637 CFDictionarySetValue(entity
,
2638 kSCPropNetInterfaceHardware
,
2639 *configurations
[interfaceIndex
].entity_hardware
);
2642 CFDictionarySetValue(entity
,
2643 kSCPropNetInterfaceHardware
,
2644 interfacePrivate
->interface_type
);
2647 // add the localized display name (which will only be used when/if the
2648 // interface is removed from the system)
2649 CFDictionarySetValue(entity
,
2650 kSCPropUserDefinedName
,
2651 SCNetworkInterfaceGetLocalizedDisplayName(interface
));
2653 // note that this is a V.92 capable modem
2654 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeModem
) &&
2655 interfacePrivate
->modemIsV92
) {
2659 num
= CFNumberCreate(NULL
, kCFNumberIntType
, &one
);
2660 CFDictionarySetValue(entity
,
2661 kSCPropNetInterfaceSupportsModemOnHold
,
2670 #if !TARGET_OS_IPHONE
2671 static SCNetworkInterfaceRef
2672 findInterface(CFArrayRef interfaces
, CFStringRef match_if
)
2677 n
= CFArrayGetCount(interfaces
);
2678 for (i
= 0; i
< n
; i
++) {
2679 SCNetworkInterfaceRef interface
= CFArrayGetValueAtIndex(interfaces
, i
);
2680 CFStringRef interfaceName
;
2682 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
2683 if ((interfaceName
!= NULL
) && CFEqual(interfaceName
, match_if
)) {
2684 CFRetain(interface
);
2693 static SCNetworkInterfaceRef
2694 findBondInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
2697 SCNetworkInterfaceRef interface
= NULL
;
2699 if (prefs
== NULL
) {
2703 // check if the interface is an Ethernet Bond
2704 bonds
= SCBondInterfaceCopyAll(prefs
);
2705 if (bonds
!= NULL
) {
2706 interface
= findInterface(bonds
, ifDevice
);
2712 static SCNetworkInterfaceRef
2713 findVLANInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
2715 SCNetworkInterfaceRef interface
= NULL
;
2718 if (prefs
== NULL
) {
2722 // check if the interface is a VLAN
2723 vlans
= SCVLANInterfaceCopyAll(prefs
);
2724 if (vlans
!= NULL
) {
2725 interface
= findInterface(vlans
, ifDevice
);
2730 #endif // !TARGET_OS_IPHONE
2733 SCNetworkInterfaceRef
2734 _SCNetworkInterfaceCreateWithBSDName(CFAllocatorRef allocator
,
2735 CFStringRef bsdName
,
2738 CFMutableDictionaryRef entity
;
2739 SCNetworkInterfaceRef interface
;
2741 entity
= CFDictionaryCreateMutable(NULL
,
2743 &kCFTypeDictionaryKeyCallBacks
,
2744 &kCFTypeDictionaryValueCallBacks
);
2745 CFDictionarySetValue(entity
, kSCPropNetInterfaceDeviceName
, bsdName
);
2746 #if !TARGET_OS_IPHONE
2747 if ((flags
& kIncludeBondInterfaces
) == 0) {
2748 CFDictionarySetValue(entity
, CFSTR("_NO_BOND_INTERFACES_"), kCFBooleanTrue
);
2750 if ((flags
& kIncludeVLANInterfaces
) == 0) {
2751 CFDictionarySetValue(entity
, CFSTR("_NO_VLAN_INTERFACES_"), kCFBooleanTrue
);
2753 #endif // !TARGET_OS_IPHONE
2754 interface
= _SCNetworkInterfaceCreateWithEntity(NULL
, entity
, NULL
);
2762 __SCNetworkInterfaceSetService(SCNetworkInterfaceRef interface
,
2763 SCNetworkServiceRef service
)
2765 SCNetworkInterfacePrivateRef interfacePrivate
;
2766 SCNetworkServicePrivateRef servicePrivate
;
2768 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2769 if (interfacePrivate
->prefs
!= NULL
) {
2770 CFRelease(interfacePrivate
->prefs
);
2771 interfacePrivate
->prefs
= NULL
;
2773 if (interfacePrivate
->serviceID
!= NULL
) {
2774 CFRelease(interfacePrivate
->serviceID
);
2775 interfacePrivate
->serviceID
= NULL
;
2778 servicePrivate
= (SCNetworkServicePrivateRef
)service
;
2779 if (servicePrivate
->prefs
!= NULL
) {
2780 interfacePrivate
->prefs
= CFRetain(servicePrivate
->prefs
);
2782 if (servicePrivate
->serviceID
!= NULL
) {
2783 interfacePrivate
->serviceID
= CFRetain(servicePrivate
->serviceID
);
2791 _SCNetworkInterfaceMatchesName(CFStringRef name
, CFStringRef key
)
2796 if (bundle
== NULL
) {
2801 if (!isA_CFString(name
)) {
2802 // if no interface "name"
2806 // check non-localized name for a match
2807 str
= copy_interface_string(bundle
, key
, FALSE
);
2809 match
= CFEqual(name
, str
);
2816 // check localized name for a match
2817 str
= copy_interface_string(bundle
, key
, TRUE
);
2819 match
= CFEqual(name
, str
);
2830 SCNetworkInterfaceRef
2831 _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef allocator
,
2832 CFDictionaryRef interface_entity
,
2833 SCNetworkServiceRef service
)
2835 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
2836 CFStringRef ifDevice
;
2837 CFStringRef ifName
= NULL
;
2838 CFStringRef ifSubType
;
2840 CFStringRef ifUnique
;
2841 CFArrayRef matching_interfaces
= NULL
;
2843 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
2844 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
2846 ifType
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceType
);
2847 if (ifType
== NULL
) {
2849 * The interface "Type" was not specified. We'll make an
2850 * assumption that this is an "Ethernet" interface. If a
2851 * real interface exists with the provided interface name
2852 * then the actual type will be set accordingly. If not, we'll
2853 * end up crafting an "Ethernet" SCNetworkInterface which
2854 * will keep the rest of the configuration APIs happy.
2856 ifType
= kSCValNetInterfaceTypeEthernet
;
2859 if (!isA_CFString(ifType
)) {
2863 ifSubType
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceSubType
);
2864 if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
2865 if (!isA_CFString(ifSubType
)) {
2870 ifDevice
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceDeviceName
);
2871 ifUnique
= CFDictionaryGetValue(interface_entity
, CFSTR("DeviceUniqueIdentifier"));
2873 if (CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
) ||
2874 CFEqual(ifType
, kSCValNetInterfaceTypeFireWire
) ||
2875 (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) && CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPoE
))) {
2876 char bsdName
[IFNAMSIZ
+ 1];
2877 CFMutableDictionaryRef matching
;
2879 if (!isA_CFString(ifDevice
)) {
2883 if (_SC_cfstring_to_cstring(ifDevice
, bsdName
, sizeof(bsdName
), kCFStringEncodingASCII
) == NULL
) {
2887 matching
= IOBSDNameMatching(masterPort
, 0, bsdName
);
2888 if (matching
== NULL
) {
2892 // note: the "matching" dictionary will be consumed by the following
2893 matching_interfaces
= findMatchingInterfaces(matching
, processNetworkInterface
);
2895 } else if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
2896 if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPSerial
)) {
2897 CFDictionaryRef matching
;
2898 CFStringRef match_keys
[2];
2899 CFStringRef match_vals
[2];
2901 if (!isA_CFString(ifDevice
)) {
2905 match_keys
[0] = CFSTR(kIOProviderClassKey
);
2906 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
2908 match_keys
[1] = CFSTR(kIOTTYBaseNameKey
);
2909 match_vals
[1] = ifDevice
;
2911 matching
= CFDictionaryCreate(NULL
,
2912 (const void **)match_keys
,
2913 (const void **)match_vals
,
2914 sizeof(match_keys
)/sizeof(match_keys
[0]),
2915 &kCFTypeDictionaryKeyCallBacks
,
2916 &kCFTypeDictionaryValueCallBacks
);
2918 // note: the "matching" dictionary will be consumed by the following
2919 matching_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
);
2921 if (ifUnique
== NULL
) {
2923 Boolean useDeviceName
= TRUE
;
2925 n
= (matching_interfaces
!= NULL
) ? CFArrayGetCount(matching_interfaces
) : 0;
2929 for (i
= 0; i
< n
; i
++) {
2930 SCNetworkInterfacePrivateRef scanPrivate
;
2932 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
2933 if (scanPrivate
->entity_device_unique
!= NULL
) {
2934 useDeviceName
= FALSE
;
2940 if (useDeviceName
) {
2941 if (matching_interfaces
!= NULL
) {
2942 CFRelease(matching_interfaces
);
2945 match_keys
[1] = CFSTR(kIOTTYDeviceKey
);
2946 matching
= CFDictionaryCreate(NULL
,
2947 (const void **)match_keys
,
2948 (const void **)match_vals
,
2949 sizeof(match_keys
)/sizeof(match_keys
[0]),
2950 &kCFTypeDictionaryKeyCallBacks
,
2951 &kCFTypeDictionaryValueCallBacks
);
2953 // note: the "matching" dictionary will be consumed by the following
2954 matching_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
);
2957 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypeL2TP
)) {
2958 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
2959 kSCNetworkInterfaceTypeL2TP
);
2960 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPTP
)) {
2961 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
2962 kSCNetworkInterfaceTypePPTP
);
2964 // XXX do we allow non-Apple variants of PPP??? XXX
2965 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
2968 } else if (CFEqual(ifType
, kSCValNetInterfaceType6to4
)) {
2969 if (!isA_CFString(ifDevice
)) {
2973 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
2974 kSCNetworkInterfaceType6to4
);
2975 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeIPSec
)) {
2976 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
2977 kSCNetworkInterfaceTypeIPSec
);
2978 } else if ((CFStringFind(ifType
, CFSTR("."), 0).location
!= kCFNotFound
) && (ifDevice
== NULL
)) {
2979 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
2983 if (matching_interfaces
!= NULL
) {
2985 SCPreferencesRef prefs
;
2987 n
= CFArrayGetCount(matching_interfaces
);
2990 interfacePrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, 0);
2991 if (_SC_CFEqual(ifUnique
, interfacePrivate
->entity_device_unique
)) {
2992 // if the unique ID's match
2993 CFRetain(interfacePrivate
);
2997 interfacePrivate
= NULL
;
3000 if (!CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
)) {
3003 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), NULL
);
3004 if (prefs
== NULL
) {
3007 #if !TARGET_OS_IPHONE
3008 if (!CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_VLAN_INTERFACES_"))) {
3009 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findVLANInterface(prefs
, ifDevice
);
3011 if ((interfacePrivate
== NULL
)
3012 && !CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_BOND_INTERFACES_"))) {
3013 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findBondInterface(prefs
, ifDevice
);
3015 #endif // !TARGET_OS_IPHONE
3019 if (ifUnique
!= NULL
) {
3022 // we are looking for an interface with a unique ID
3023 // so let's try to focus our choices
3024 for (i
= 0; i
< n
; i
++) {
3025 SCNetworkInterfacePrivateRef scanPrivate
;
3027 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
3028 if (_SC_CFEqual(ifUnique
, scanPrivate
->entity_device_unique
)) {
3029 if (interfacePrivate
!= NULL
) {
3030 // if we've matched more than one interface
3031 interfacePrivate
= NULL
;
3034 interfacePrivate
= scanPrivate
;
3037 } else if (CFDictionaryGetValueIfPresent(interface_entity
,
3038 kSCPropUserDefinedName
,
3039 (const void **)&ifName
)) {
3042 // we don't have a unique ID but do have an interface
3043 // name. If the matching interfaces do have IDs than
3044 // we can try to focus our choices using the name
3045 for (i
= 0; i
< n
; i
++) {
3046 SCNetworkInterfacePrivateRef scanPrivate
;
3048 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
3049 if (scanPrivate
->entity_device_unique
!= NULL
) {
3050 SCNetworkInterfaceRef scan
= (SCNetworkInterfaceRef
)scanPrivate
;
3051 CFStringRef scanName
;
3053 scanName
= __SCNetworkInterfaceGetNonLocalizedDisplayName(scan
);
3054 if ((scanName
!= NULL
) && !_SC_CFEqual(ifName
, scanName
)) {
3055 continue; // if not the same display name
3059 if (interfacePrivate
!= NULL
) {
3060 // if we've matched more than one interface
3061 interfacePrivate
= NULL
;
3064 interfacePrivate
= scanPrivate
;
3067 if (interfacePrivate
== NULL
) {
3068 SCLog(TRUE
, LOG_ERR
, CFSTR("_SCNetworkInterfaceCreateWithEntity() failed, more than one interface matches %@"), ifDevice
);
3069 interfacePrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, 0);
3071 CFRetain(interfacePrivate
);
3074 CFRelease(matching_interfaces
);
3079 if (interfacePrivate
== NULL
) {
3081 * if device not present on this system
3083 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
, NULL
);
3084 interfacePrivate
->entity_type
= ifType
;
3085 interfacePrivate
->entity_subtype
= ifSubType
;
3086 interfacePrivate
->entity_device
= (ifDevice
!= NULL
) ? CFStringCreateCopy(NULL
, ifDevice
) : NULL
;
3087 interfacePrivate
->entity_device_unique
= (ifUnique
!= NULL
) ? CFStringCreateCopy(NULL
, ifUnique
) : NULL
;
3089 if (CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
)) {
3090 CFStringRef entity_hardware
;
3092 entity_hardware
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceHardware
);
3093 if (isA_CFString((entity_hardware
)) &&
3094 CFEqual(entity_hardware
, kSCEntNetAirPort
)) {
3095 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
3096 interfacePrivate
->sort_order
= kSortAirPort
;
3100 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
3102 name
= CFDictionaryGetValue(interface_entity
, kSCPropUserDefinedName
);
3103 if (_SCNetworkInterfaceMatchesName(name
, CFSTR("iPhone"))) {
3104 interfacePrivate
->sort_order
= kSortTethered
;
3105 } else if (_SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan"))) {
3106 interfacePrivate
->sort_order
= kSortBluetoothPAN
;
3108 interfacePrivate
->sort_order
= kSortEthernet
;
3111 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeFireWire
)) {
3112 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeFireWire
;
3113 interfacePrivate
->sort_order
= kSortFireWire
;
3114 } else if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
3115 if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPoE
)) {
3116 CFStringRef entity_hardware
;
3118 entity_hardware
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceHardware
);
3119 if (isA_CFString((entity_hardware
)) &&
3120 CFEqual(entity_hardware
, kSCEntNetAirPort
)) {
3121 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
3122 interfacePrivate
->sort_order
= kSortAirPort
;
3124 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
3125 interfacePrivate
->sort_order
= kSortEthernet
;
3127 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPSerial
)) {
3128 if (CFStringHasPrefix(ifDevice
, CFSTR("Bluetooth"))) {
3129 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBluetooth
;
3130 interfacePrivate
->sort_order
= kSortBluetooth
;
3131 } else if (CFStringHasPrefix(ifDevice
, CFSTR("irda"))) {
3132 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIrDA
;
3133 interfacePrivate
->sort_order
= kSortIrDA
;
3134 } else if (CFStringHasPrefix(ifDevice
, CFSTR("wwan"))) {
3135 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeWWAN
;
3136 interfacePrivate
->sort_order
= kSortWWAN
;
3138 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeModem
;
3139 interfacePrivate
->sort_order
= kSortModem
;
3143 CFRelease(interfacePrivate
);
3144 interfacePrivate
= (SCNetworkInterfacePrivateRef
)kSCNetworkInterfaceIPv4
;
3145 CFRetain(interfacePrivate
);
3147 } else if (CFStringFind(ifType
, CFSTR("."), 0).location
!= kCFNotFound
) {
3148 // if vendor interface
3149 interfacePrivate
->interface_type
= ifType
;
3151 // if unknown interface
3152 CFRelease(interfacePrivate
);
3153 interfacePrivate
= NULL
;
3157 if ((interfacePrivate
!= NULL
) && (service
!= NULL
)) {
3158 __SCNetworkInterfaceSetService((SCNetworkInterfaceRef
)interfacePrivate
,
3160 #if !TARGET_OS_IPHONE
3161 // set prefs & serviceID to VLANs and Bonds
3162 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBond
)) {
3167 members
= SCBondInterfaceGetMemberInterfaces((SCNetworkInterfaceRef
)interfacePrivate
);
3168 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
3169 for (i
= 0; i
< n
; i
++) {
3170 SCNetworkInterfaceRef member
;
3172 member
= CFArrayGetValueAtIndex(members
, i
);
3173 __SCNetworkInterfaceSetService(member
, service
);
3175 } else if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeVLAN
)) {
3176 SCNetworkInterfaceRef vlan_physical
;
3178 vlan_physical
= SCVLANInterfaceGetPhysicalInterface((SCNetworkInterfaceRef
)interfacePrivate
);
3179 if (vlan_physical
!= NULL
) {
3180 __SCNetworkInterfaceSetService(vlan_physical
, service
);
3183 #endif // !TARGET_OS_IPHONE
3186 if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
3187 SCNetworkInterfaceRef parent
;
3190 parent
= SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef
)interfacePrivate
,
3191 kSCNetworkInterfaceTypePPP
);
3192 CFRelease(interfacePrivate
);
3193 interfacePrivate
= (SCNetworkInterfacePrivateRef
)parent
;
3196 return (SCNetworkInterfaceRef
)interfacePrivate
;
3201 #pragma mark SCNetworkInterface APIs
3206 __SCNetworkInterfaceCopyAll_IONetworkInterface(void)
3208 CFDictionaryRef matching
;
3209 CFArrayRef new_interfaces
;
3211 // get Ethernet, Firewire, and AirPort interfaces
3213 matching
= IOServiceMatching(kIONetworkInterfaceClass
);
3214 new_interfaces
= findMatchingInterfaces(matching
, processNetworkInterface
);
3216 return new_interfaces
;
3222 __SCNetworkInterfaceCopyAll_Modem()
3224 CFDictionaryRef matching
;
3225 CFStringRef match_keys
[2];
3226 CFStringRef match_vals
[2];
3227 CFArrayRef new_interfaces
;
3229 match_keys
[0] = CFSTR(kIOProviderClassKey
);
3230 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
3232 match_keys
[1] = CFSTR(kIOSerialBSDTypeKey
);
3233 match_vals
[1] = CFSTR(kIOSerialBSDModemType
);
3235 matching
= CFDictionaryCreate(NULL
,
3236 (const void **)match_keys
,
3237 (const void **)match_vals
,
3238 sizeof(match_keys
)/sizeof(match_keys
[0]),
3239 &kCFTypeDictionaryKeyCallBacks
,
3240 &kCFTypeDictionaryValueCallBacks
);
3241 new_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
);
3243 return new_interfaces
;
3249 __SCNetworkInterfaceCopyAll_RS232()
3251 CFDictionaryRef matching
;
3252 CFStringRef match_keys
[2];
3253 CFStringRef match_vals
[2];
3254 CFArrayRef new_interfaces
;
3256 match_keys
[0] = CFSTR(kIOProviderClassKey
);
3257 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
3259 match_keys
[1] = CFSTR(kIOSerialBSDTypeKey
);
3260 match_vals
[1] = CFSTR(kIOSerialBSDRS232Type
);
3262 matching
= CFDictionaryCreate(NULL
,
3263 (const void **)match_keys
,
3264 (const void **)match_vals
,
3265 sizeof(match_keys
)/sizeof(match_keys
[0]),
3266 &kCFTypeDictionaryKeyCallBacks
,
3267 &kCFTypeDictionaryValueCallBacks
);
3268 new_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
);
3270 return new_interfaces
;
3275 add_interfaces(CFMutableArrayRef all_interfaces
, CFArrayRef new_interfaces
)
3280 n
= CFArrayGetCount(new_interfaces
);
3281 for (i
= 0; i
< n
; i
++) {
3282 CFStringRef bsdName
;
3283 SCNetworkInterfaceRef interface
;
3285 interface
= CFArrayGetValueAtIndex(new_interfaces
, i
);
3286 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
3287 if (bsdName
!= NULL
) {
3288 CFArrayAppendValue(all_interfaces
, interface
);
3297 __waitForInterfaces()
3302 SCDynamicStoreRef store
;
3304 store
= SCDynamicStoreCreate(NULL
, CFSTR("SCNetworkInterfaceCopyAll"), NULL
, NULL
);
3305 if (store
== NULL
) {
3309 key
= SCDynamicStoreKeyCreate(NULL
, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin
);
3310 keys
= CFArrayCreate(NULL
, (const void **)&key
, 1, &kCFTypeArrayCallBacks
);
3311 ok
= SCDynamicStoreSetNotificationKeys(store
, keys
, NULL
);
3314 SCLog(TRUE
, LOG_ERR
,
3315 CFSTR("SCDynamicStoreSetNotificationKeys() failed: %s"), SCErrorString(SCError()));
3320 CFArrayRef changedKeys
;
3321 CFDictionaryRef dict
;
3322 Boolean quiet
= FALSE
;
3325 dict
= SCDynamicStoreCopyValue(store
, key
);
3327 if (isA_CFDictionary(dict
) &&
3328 (CFDictionaryContainsKey(dict
, CFSTR("*QUIET*")) ||
3329 CFDictionaryContainsKey(dict
, CFSTR("*TIMEOUT*")))) {
3338 ok
= SCDynamicStoreNotifyWait(store
);
3340 SCLog(TRUE
, LOG_ERR
,
3341 CFSTR("SCDynamicStoreNotifyWait() failed: %s"), SCErrorString(SCError()));
3345 changedKeys
= SCDynamicStoreCopyNotifiedKeys(store
);
3346 if (changedKeys
!= NULL
) {
3347 CFRelease(changedKeys
);
3359 CFArrayRef
/* of SCNetworkInterfaceRef's */
3360 SCNetworkInterfaceCopyAll()
3362 CFMutableArrayRef all_interfaces
;
3363 CFArrayRef new_interfaces
;
3364 #if !TARGET_OS_IPHONE
3365 SCPreferencesRef prefs
;
3366 #endif // !TARGET_OS_IPHONE
3368 /* initialize runtime */
3369 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
3371 /* wait for IOKit to quiesce */
3372 pthread_once(&iokit_quiet
, __waitForInterfaces
);
3374 all_interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3376 // get Ethernet, Firewire, and AirPort interfaces
3377 new_interfaces
= __SCNetworkInterfaceCopyAll_IONetworkInterface();
3378 if (new_interfaces
!= NULL
) {
3379 add_interfaces(all_interfaces
, new_interfaces
);
3380 CFRelease(new_interfaces
);
3383 // get Modem interfaces
3384 new_interfaces
= __SCNetworkInterfaceCopyAll_Modem();
3385 if (new_interfaces
!= NULL
) {
3386 add_interfaces(all_interfaces
, new_interfaces
);
3387 CFRelease(new_interfaces
);
3390 // get serial (RS232) interfaces
3391 new_interfaces
= __SCNetworkInterfaceCopyAll_RS232();
3392 if (new_interfaces
!= NULL
) {
3393 add_interfaces(all_interfaces
, new_interfaces
);
3394 CFRelease(new_interfaces
);
3397 #if !TARGET_OS_IPHONE
3398 // get virtual network interfaces (Bond, VLAN)
3399 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterfaceCopyAll"), NULL
);
3400 if (prefs
!= NULL
) {
3401 new_interfaces
= SCBondInterfaceCopyAll(prefs
);
3402 if (new_interfaces
!= NULL
) {
3403 add_interfaces(all_interfaces
, new_interfaces
);
3404 CFRelease(new_interfaces
);
3407 new_interfaces
= SCVLANInterfaceCopyAll(prefs
);
3408 if (new_interfaces
!= NULL
) {
3409 add_interfaces(all_interfaces
, new_interfaces
);
3410 CFRelease(new_interfaces
);
3415 #endif // !TARGET_OS_IPHONE
3417 // all interfaces have been identified, order and return
3418 sort_interfaces(all_interfaces
);
3420 return all_interfaces
;
3424 CFArrayRef
/* of kSCNetworkInterfaceTypeXXX CFStringRef's */
3425 SCNetworkInterfaceGetSupportedInterfaceTypes(SCNetworkInterfaceRef interface
)
3428 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3430 if (!isA_SCNetworkInterface(interface
)) {
3431 _SCErrorSet(kSCStatusInvalidArgument
);
3435 if (interfacePrivate
->supported_interface_types
!= NULL
) {
3439 i
= findConfiguration(interfacePrivate
->interface_type
);
3440 if (i
!= kCFNotFound
) {
3441 if (configurations
[i
].supported_interfaces
!= doNone
) {
3442 interfacePrivate
->supported_interface_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3443 if (configurations
[i
].supported_interfaces
& do6to4
) {
3444 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceType6to4
);
3446 if (configurations
[i
].supported_interfaces
& doL2TP
) {
3447 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeL2TP
);
3449 if (configurations
[i
].supported_interfaces
& doPPP
) {
3450 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypePPP
);
3452 if (configurations
[i
].supported_interfaces
& doPPTP
) {
3453 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypePPTP
);
3455 if (configurations
[i
].supported_interfaces
& doIPSec
) {
3456 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeIPSec
);
3463 return interfacePrivate
->supported_interface_types
;
3467 CFArrayRef
/* of kSCNetworkProtocolTypeXXX CFStringRef's */
3468 SCNetworkInterfaceGetSupportedProtocolTypes(SCNetworkInterfaceRef interface
)
3471 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3473 if (!isA_SCNetworkInterface(interface
)) {
3474 _SCErrorSet(kSCStatusInvalidArgument
);
3478 if (interfacePrivate
->supported_protocol_types
!= NULL
) {
3482 i
= findConfiguration(interfacePrivate
->interface_type
);
3483 if (i
!= kCFNotFound
) {
3484 if (configurations
[i
].supported_protocols
!= doNone
) {
3485 interfacePrivate
->supported_protocol_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3486 #if !TARGET_OS_IPHONE
3487 if (configurations
[i
].supported_protocols
& doAppleTalk
) {
3488 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeAppleTalk
);
3490 #endif // !TARGET_OS_IPHONE
3491 if (configurations
[i
].supported_protocols
& doDNS
) {
3492 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeDNS
);
3494 if (configurations
[i
].supported_protocols
& doIPv4
) {
3495 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeIPv4
);
3497 if (configurations
[i
].supported_protocols
& doIPv6
) {
3498 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeIPv6
);
3500 if (configurations
[i
].supported_protocols
& doProxies
) {
3501 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeProxies
);
3503 #if !TARGET_OS_IPHONE
3504 if (configurations
[i
].supported_protocols
& doSMB
) {
3505 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeSMB
);
3507 #endif // !TARGET_OS_IPHONE
3513 return interfacePrivate
->supported_protocol_types
;
3517 SCNetworkInterfaceRef
3518 SCNetworkInterfaceCreateWithInterface(SCNetworkInterfaceRef child
, CFStringRef interfaceType
)
3520 SCNetworkInterfacePrivateRef childPrivate
= (SCNetworkInterfacePrivateRef
)child
;
3522 SCNetworkInterfacePrivateRef parentPrivate
;
3524 if (!isA_SCNetworkInterface(child
)) {
3525 _SCErrorSet(kSCStatusInvalidArgument
);
3529 if (!isA_CFString(interfaceType
)) {
3530 _SCErrorSet(kSCStatusInvalidArgument
);
3534 childIndex
= findConfiguration(childPrivate
->interface_type
);
3536 parentPrivate
= __SCNetworkInterfaceCreatePrivate(NULL
,
3538 childPrivate
->prefs
,
3539 childPrivate
->serviceID
,
3541 if (parentPrivate
== NULL
) {
3542 _SCErrorSet(kSCStatusFailed
);
3546 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
3547 parentPrivate
->interface_type
= kSCNetworkInterfaceTypePPP
;
3548 parentPrivate
->entity_type
= kSCValNetInterfaceTypePPP
;
3551 if (childIndex
!= kCFNotFound
) {
3552 if (configurations
[childIndex
].ppp_subtype
!= NULL
) {
3553 parentPrivate
->entity_subtype
= *configurations
[childIndex
].ppp_subtype
;
3555 // sorry, the child interface does not support PPP
3559 // if the child's interface type not known, use the child entities "Type"
3560 parentPrivate
->entity_subtype
= childPrivate
->entity_type
;
3563 if (childPrivate
->entity_device
!= NULL
) {
3564 parentPrivate
->entity_device
= CFStringCreateCopy(NULL
, childPrivate
->entity_device
);
3567 if (childPrivate
->entity_device_unique
!= NULL
) {
3568 parentPrivate
->entity_device_unique
= CFStringCreateCopy(NULL
, childPrivate
->entity_device_unique
);
3570 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
3571 if ((childIndex
== kCFNotFound
) ||
3572 ((configurations
[childIndex
].supported_interfaces
& doL2TP
) != doL2TP
)) {
3573 // if the child interface does not support L2TP
3576 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeL2TP
;
3577 parentPrivate
->localized_key
= CFSTR("l2tp");
3578 parentPrivate
->entity_type
= kSCEntNetL2TP
; // interface config goes into "L2TP"
3579 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPTP
)) {
3580 if ((childIndex
== kCFNotFound
) ||
3581 ((configurations
[childIndex
].supported_interfaces
& doPPTP
) != doPPTP
)) {
3582 // if the child interface does not support PPTP
3585 parentPrivate
->interface_type
= kSCNetworkInterfaceTypePPTP
;
3586 parentPrivate
->localized_key
= CFSTR("pptp");
3587 parentPrivate
->entity_type
= kSCEntNetPPTP
; // interface config goes into "PPTP"
3588 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceType6to4
)) {
3589 if ((childIndex
== kCFNotFound
) ||
3590 ((configurations
[childIndex
].supported_interfaces
& do6to4
) != do6to4
)) {
3591 // if the child interface does not support 6to4
3595 parentPrivate
->interface_type
= kSCNetworkInterfaceType6to4
;
3596 parentPrivate
->localized_key
= CFSTR("6to4");
3597 parentPrivate
->entity_type
= kSCValNetInterfaceType6to4
;
3598 parentPrivate
->entity_device
= CFRetain(CFSTR("stf0"));
3599 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
3600 if ((childIndex
== kCFNotFound
) ||
3601 ((configurations
[childIndex
].supported_interfaces
& doIPSec
) != doIPSec
)) {
3602 // if the child interface does not support IPSec
3605 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeIPSec
;
3606 parentPrivate
->localized_key
= CFSTR("ipsec");
3607 parentPrivate
->entity_type
= kSCValNetInterfaceTypeIPSec
;
3608 } else if (CFStringFind(interfaceType
, CFSTR("."), 0).location
!= kCFNotFound
) {
3609 // if custom interface type
3610 parentPrivate
->interface_type
= interfaceType
;
3611 parentPrivate
->entity_type
= interfaceType
; // interface config goes into a
3612 // a dictionary with the same
3613 // name as the interfaceType
3615 // unknown interface type
3619 if (childPrivate
->overrides
!= NULL
) {
3620 parentPrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, childPrivate
->overrides
);
3623 // The following change handles the case where a user has both an Ethernet and
3624 // PPPoE network service. Because a PPPoE service is typically associated with
3625 // an ISP we want it to be sorted higher in the service order.
3626 if ((parentPrivate
->entity_subtype
!= NULL
) &&
3627 (CFEqual(parentPrivate
->entity_subtype
, kSCValNetInterfaceSubTypePPPoE
))) {
3628 if ((childPrivate
->interface_type
!= NULL
) &&
3629 (CFEqual(childPrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
))) {
3630 parentPrivate
->sort_order
= kSortAirportPPP
;
3632 parentPrivate
->sort_order
= kSortEthernetPPP
;
3635 // set sort order of the parent to match the child interface
3636 parentPrivate
->sort_order
= childPrivate
->sort_order
;
3639 return (SCNetworkInterfaceRef
)parentPrivate
;
3643 CFRelease(parentPrivate
);
3644 _SCErrorSet(kSCStatusInvalidArgument
);
3651 __SCNetworkInterfaceGetDefaultConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
)
3653 CFDictionaryRef config
= NULL
;
3654 CFStringRef defaultType
;
3655 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3657 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
3658 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
3660 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
3661 if (defaultType
!= NULL
) {
3665 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
3666 SCNetworkSetGetSetID(set
), // set
3667 interfacePrivate
->entity_device
, // interface
3668 defaultType
); // entity
3670 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
3673 if (config
== NULL
) {
3674 // if the "set" does not have a saved configuration, use
3675 // the [template] "interface" configuration
3676 if (interfacePrivate
->unsaved
!= NULL
) {
3677 config
= CFDictionaryGetValue(interfacePrivate
->unsaved
, defaultType
);
3678 if (config
== (CFDictionaryRef
)kCFNull
) {
3683 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
3694 static CFDictionaryRef
3695 __SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface
,
3696 CFStringRef extendedType
)
3698 CFDictionaryRef config
= NULL
;
3699 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3702 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
3703 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
3705 paths
= copyConfigurationPaths(interfacePrivate
, extendedType
);
3706 if (paths
!= NULL
) {
3709 path
= CFArrayGetValueAtIndex(paths
, 0);
3710 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
3714 if (interfacePrivate
->unsaved
!= NULL
) {
3715 config
= CFDictionaryGetValue(interfacePrivate
->unsaved
, extendedType
);
3716 if (config
== (CFDictionaryRef
)kCFNull
) {
3722 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
3731 SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface
)
3733 CFDictionaryRef config
;
3734 CFStringRef defaultType
;
3736 if (!isA_SCNetworkInterface(interface
)) {
3737 _SCErrorSet(kSCStatusInvalidArgument
);
3741 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
3742 if (defaultType
== NULL
) {
3746 config
= __SCNetworkInterfaceGetConfiguration(interface
, defaultType
);
3747 if (config
== NULL
) {
3748 if (CFEqual(defaultType
, kSCEntNetAirPort
)) {
3749 SCNetworkInterfacePrivateRef interfacePrivate
;
3752 // if AirPort interface, check for a per-service config
3753 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3754 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
3755 interfacePrivate
->serviceID
, // service
3756 kSCEntNetAirPort
); // entity
3757 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
3761 if (config
== NULL
) {
3762 _SCErrorSet(kSCStatusOK
);
3770 SCNetworkInterfaceGetExtendedConfiguration(SCNetworkInterfaceRef interface
,
3771 CFStringRef extendedType
)
3773 CFDictionaryRef config
;
3775 if (!isA_SCNetworkInterface(interface
)) {
3776 _SCErrorSet(kSCStatusInvalidArgument
);
3780 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, TRUE
)) {
3781 _SCErrorSet(kSCStatusInvalidArgument
);
3785 config
= __SCNetworkInterfaceGetConfiguration(interface
, extendedType
);
3786 if (config
== NULL
) {
3787 _SCErrorSet(kSCStatusOK
);
3795 SCNetworkInterfaceGetBSDName(SCNetworkInterfaceRef interface
)
3797 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3799 if (!isA_SCNetworkInterface(interface
)) {
3800 _SCErrorSet(kSCStatusInvalidArgument
);
3804 if ((interfacePrivate
->interface
!= NULL
) &&
3805 (interfacePrivate
->interface
!= kSCNetworkInterfaceIPv4
)) {
3806 _SCErrorSet(kSCStatusOK
);
3810 return interfacePrivate
->entity_device
;
3815 SCNetworkInterfaceGetHardwareAddressString(SCNetworkInterfaceRef interface
)
3817 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3819 if (!isA_SCNetworkInterface(interface
)) {
3820 _SCErrorSet(kSCStatusInvalidArgument
);
3824 if ((interfacePrivate
->address
!= NULL
) &&
3825 (interfacePrivate
->addressString
== NULL
)) {
3829 char mac
[sizeof("xx:xx:xx:xx:xx:xx:xx:xx")];
3832 bp
= (uint8_t *)CFDataGetBytePtr(interfacePrivate
->address
);
3833 n
= CFDataGetLength(interfacePrivate
->address
) * 3;
3835 if (n
> sizeof(mac
)) {
3836 mac_p
= CFAllocatorAllocate(NULL
, 0, n
);
3839 for (cp
= mac_p
; n
> 0; n
-= 3) {
3840 cp
+= snprintf(cp
, n
, "%2.2x:", *bp
++);
3843 interfacePrivate
->addressString
= CFStringCreateWithCString(NULL
, mac_p
, kCFStringEncodingUTF8
);
3844 if (mac_p
!= mac
) CFAllocatorDeallocate(NULL
, mac_p
);
3847 return interfacePrivate
->addressString
;
3851 SCNetworkInterfaceRef
3852 SCNetworkInterfaceGetInterface(SCNetworkInterfaceRef interface
)
3854 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3856 if (!isA_SCNetworkInterface(interface
)) {
3857 _SCErrorSet(kSCStatusInvalidArgument
);
3861 return interfacePrivate
->interface
;
3866 SCNetworkInterfaceGetInterfaceType(SCNetworkInterfaceRef interface
)
3868 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3870 if (!isA_SCNetworkInterface(interface
)) {
3871 _SCErrorSet(kSCStatusInvalidArgument
);
3875 return interfacePrivate
->interface_type
;
3880 copy_interface_string(CFBundleRef bundle
, CFStringRef key
, Boolean localized
)
3882 CFStringRef str
= NULL
;
3885 str
= CFBundleCopyLocalizedString(bundle
,
3888 NETWORKINTERFACE_LOCALIZATIONS
);
3890 str
= _SC_CFBundleCopyNonLocalizedString(bundle
,
3893 NETWORKINTERFACE_LOCALIZATIONS
);
3901 copy_display_name(SCNetworkInterfaceRef interface
, Boolean localized
, Boolean oldLocalization
)
3903 CFMutableStringRef local
;
3906 local
= CFStringCreateMutable(NULL
, 0);
3908 while (interface
!= NULL
) {
3909 Boolean added
= FALSE
;
3910 SCNetworkInterfaceRef child
= NULL
;
3911 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3913 if ((interfacePrivate
->interface
!= NULL
) &&
3914 (interfacePrivate
->interface
!= kSCNetworkInterfaceIPv4
)) {
3915 child
= interfacePrivate
->interface
;
3918 if ((bundle
!= NULL
) && (interfacePrivate
->localized_key
!= NULL
)) {
3920 CFStringRef key
= interfacePrivate
->localized_key
;
3922 if (oldLocalization
) {
3923 key
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("X-%@"),
3924 interfacePrivate
->localized_key
);
3926 fmt
= copy_interface_string(bundle
, key
, localized
);
3928 CFStringAppendFormat(local
,
3931 interfacePrivate
->localized_arg1
,
3932 interfacePrivate
->localized_arg2
);
3936 if (oldLocalization
) {
3942 (interfacePrivate
->prefs
!= NULL
) &&
3943 (interfacePrivate
->serviceID
!= NULL
) &&
3945 CFDictionaryRef entity
;
3948 // check for (and use) the name of the interface when it
3949 // was last available
3950 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,
3951 interfacePrivate
->serviceID
,
3952 kSCEntNetInterface
);
3953 entity
= SCPreferencesPathGetValue(interfacePrivate
->prefs
, path
);
3955 if (isA_CFDictionary(entity
)) {
3958 name
= CFDictionaryGetValue(entity
, kSCPropUserDefinedName
);
3959 if (isA_CFString(name
)) {
3960 CFStringAppend(local
, name
);
3967 // create (non-)localized name based on the interface type
3968 CFStringAppend(local
, interfacePrivate
->interface_type
);
3970 // ... and, if this is a leaf node, the interface device
3971 if ((interfacePrivate
->entity_device
!= NULL
) && (child
== NULL
)) {
3972 CFStringAppendFormat(local
, NULL
, CFSTR(" (%@)"), interfacePrivate
->entity_device
);
3976 if (child
!= NULL
) {
3977 // if this interface is layered over another
3978 CFStringAppend(local
, CFSTR(" --> "));
3984 name
= CFStringCreateCopy(NULL
, local
);
3993 __SCNetworkInterfaceCopyXLocalizedDisplayName(SCNetworkInterfaceRef interface
)
3997 if (!isA_SCNetworkInterface(interface
)) {
3998 _SCErrorSet(kSCStatusInvalidArgument
);
4002 name
= copy_display_name(interface
, TRUE
, TRUE
);
4009 __SCNetworkInterfaceCopyXNonLocalizedDisplayName(SCNetworkInterfaceRef interface
)
4011 CFStringRef localized_name
;
4013 if (!isA_SCNetworkInterface(interface
)) {
4014 _SCErrorSet(kSCStatusInvalidArgument
);
4018 localized_name
= copy_display_name(interface
, FALSE
, TRUE
);
4019 return localized_name
;
4025 __SCNetworkInterfaceGetNonLocalizedDisplayName(SCNetworkInterfaceRef interface
)
4027 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4029 if (!isA_SCNetworkInterface(interface
)) {
4030 _SCErrorSet(kSCStatusInvalidArgument
);
4034 if (interfacePrivate
->name
== NULL
) {
4035 interfacePrivate
->name
= copy_display_name(interface
, FALSE
, FALSE
);
4038 return interfacePrivate
->name
;
4043 SCNetworkInterfaceGetLocalizedDisplayName(SCNetworkInterfaceRef interface
)
4045 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4047 if (!isA_SCNetworkInterface(interface
)) {
4048 _SCErrorSet(kSCStatusInvalidArgument
);
4052 if (interfacePrivate
->localized_name
== NULL
) {
4053 interfacePrivate
->localized_name
= copy_display_name(interface
, TRUE
, FALSE
);
4056 return interfacePrivate
->localized_name
;
4062 __SCNetworkInterfaceGetTemplateOverrides(SCNetworkInterfaceRef interface
, CFStringRef interfaceType
)
4064 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4065 CFDictionaryRef overrides
= NULL
;
4067 if (interfacePrivate
->overrides
!= NULL
) {
4068 overrides
= CFDictionaryGetValue(interfacePrivate
->overrides
, interfaceType
);
4076 SCNetworkInterfaceGetTypeID(void)
4078 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
); /* initialize runtime */
4079 return __kSCNetworkInterfaceTypeID
;
4085 __SCNetworkInterfaceSetDefaultConfiguration(SCNetworkSetRef set
,
4086 SCNetworkInterfaceRef interface
,
4087 CFStringRef defaultType
,
4088 CFDictionaryRef config
,
4091 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4094 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
4095 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4097 if (defaultType
== NULL
) {
4098 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
4099 if (defaultType
== NULL
) {
4104 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
4111 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
4112 SCNetworkSetGetSetID(set
), // set
4113 interfacePrivate
->entity_device
, // interface
4114 defaultType
); // entity
4116 ok
= __setPrefsConfiguration(interfacePrivate
->prefs
, path
, config
, FALSE
);
4119 // if configuration has been saved
4120 if (interfacePrivate
->unsaved
!= NULL
) {
4121 CFDictionaryRemoveValue(interfacePrivate
->unsaved
, defaultType
);
4122 if (CFDictionaryGetCount(interfacePrivate
->unsaved
) == 0) {
4123 CFRelease(interfacePrivate
->unsaved
);
4124 interfacePrivate
->unsaved
= NULL
;
4130 if (config
== NULL
) {
4131 // remember that we are clearing the configuration
4132 config
= (CFDictionaryRef
)kCFNull
;
4135 if (interfacePrivate
->unsaved
== NULL
) {
4136 interfacePrivate
->unsaved
= CFDictionaryCreateMutable(NULL
,
4138 &kCFTypeDictionaryKeyCallBacks
,
4139 &kCFTypeDictionaryValueCallBacks
);
4141 CFDictionarySetValue(interfacePrivate
->unsaved
, defaultType
, config
);
4144 _SCErrorSet(kSCStatusNoKey
);
4155 __SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface
,
4156 CFStringRef extendedType
,
4157 CFDictionaryRef config
,
4160 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4164 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
4165 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4167 if (extendedType
== NULL
) {
4168 extendedType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
4169 if (extendedType
== NULL
) {
4174 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
4178 paths
= copyConfigurationPaths(interfacePrivate
, extendedType
);
4179 if (paths
!= NULL
) {
4183 n
= CFArrayGetCount(paths
);
4184 for (i
= 0; i
< n
; i
++) {
4187 path
= CFArrayGetValueAtIndex(paths
, i
);
4188 ok
= __setPrefsConfiguration(interfacePrivate
->prefs
, path
, config
, FALSE
);
4195 // if configuration has been saved
4196 if (interfacePrivate
->unsaved
!= NULL
) {
4197 CFDictionaryRemoveValue(interfacePrivate
->unsaved
, extendedType
);
4198 if (CFDictionaryGetCount(interfacePrivate
->unsaved
) == 0) {
4199 CFRelease(interfacePrivate
->unsaved
);
4200 interfacePrivate
->unsaved
= NULL
;
4208 if (config
== NULL
) {
4209 // remember that we are clearing the configuration
4210 config
= (CFDictionaryRef
)kCFNull
;
4213 if (interfacePrivate
->unsaved
== NULL
) {
4214 interfacePrivate
->unsaved
= CFDictionaryCreateMutable(NULL
,
4216 &kCFTypeDictionaryKeyCallBacks
,
4217 &kCFTypeDictionaryValueCallBacks
);
4219 CFDictionarySetValue(interfacePrivate
->unsaved
, extendedType
, config
);
4222 _SCErrorSet(kSCStatusNoKey
);
4231 SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface
, CFDictionaryRef config
)
4233 CFStringRef defaultType
;
4235 if (!isA_SCNetworkInterface(interface
)) {
4236 _SCErrorSet(kSCStatusInvalidArgument
);
4240 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
4241 if (defaultType
== NULL
) {
4245 return __SCNetworkInterfaceSetConfiguration(interface
, defaultType
, config
, FALSE
);
4250 SCNetworkInterfaceSetExtendedConfiguration(SCNetworkInterfaceRef interface
,
4251 CFStringRef extendedType
,
4252 CFDictionaryRef config
)
4254 if (!isA_SCNetworkInterface(interface
)) {
4255 _SCErrorSet(kSCStatusInvalidArgument
);
4259 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, TRUE
)) {
4263 return __SCNetworkInterfaceSetConfiguration(interface
, extendedType
, config
, FALSE
);
4268 #pragma mark SCNetworkInterface [Refresh Configuration] API
4271 #ifndef kSCEntNetRefreshConfiguration
4272 #define kSCEntNetRefreshConfiguration CFSTR("RefreshConfiguration")
4273 #endif // kSCEntNetRefreshConfiguration
4276 _SCNetworkInterfaceForceConfigurationRefresh(CFStringRef ifName
)
4280 SCDynamicStoreRef store
;
4282 if (!isA_CFString(ifName
)) {
4283 _SCErrorSet(kSCStatusInvalidArgument
);
4287 store
= SCDynamicStoreCreate(NULL
, CFSTR("_SCNetworkInterfaceForceConfigurationRefresh"), NULL
, NULL
);
4288 if (store
== NULL
) {
4292 key
= SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL
,
4293 kSCDynamicStoreDomainState
,
4295 kSCEntNetRefreshConfiguration
);
4296 ok
= SCDynamicStoreNotifyValue(store
, key
);
4304 __SCNetworkInterfaceForceConfigurationRefresh_helper(SCPreferencesRef prefs
, CFStringRef ifName
)
4306 CFDataRef data
= NULL
;
4308 SCPreferencesPrivateRef prefsPrivate
= (SCPreferencesPrivateRef
)prefs
;
4309 uint32_t status
= kSCStatusOK
;
4310 CFDataRef reply
= NULL
;
4312 if (prefsPrivate
->helper
== -1) {
4313 ok
= __SCPreferencesCreate_helper(prefs
);
4319 // serialize the interface name
4320 ok
= _SCSerializeString(ifName
, &data
, NULL
, NULL
);
4325 // have the helper "refresh" the configuration
4326 status
= kSCStatusOK
;
4328 ok
= _SCHelperExec(prefsPrivate
->helper
,
4329 SCHELPER_MSG_INTERFACE_REFRESH
,
4333 if (data
!= NULL
) CFRelease(data
);
4338 if (status
!= kSCStatusOK
) {
4347 if (prefsPrivate
->helper
!= -1) {
4348 _SCHelperClose(prefsPrivate
->helper
);
4349 prefsPrivate
->helper
= -1;
4352 status
= kSCStatusAccessError
;
4357 _SCErrorSet(status
);
4363 SCNetworkInterfaceForceConfigurationRefresh(SCNetworkInterfaceRef interface
)
4366 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4368 if (!isA_SCNetworkInterface(interface
)) {
4369 _SCErrorSet(kSCStatusInvalidArgument
);
4373 ifName
= SCNetworkInterfaceGetBSDName(interface
);
4374 if (ifName
== NULL
) {
4375 _SCErrorSet(kSCStatusInvalidArgument
);
4379 if (interfacePrivate
->prefs
!= NULL
) {
4380 SCPreferencesRef prefs
= interfacePrivate
->prefs
;
4381 SCPreferencesPrivateRef prefsPrivate
= (SCPreferencesPrivateRef
)prefs
;
4383 if (prefsPrivate
->authorizationData
!= NULL
) {
4384 return __SCNetworkInterfaceForceConfigurationRefresh_helper(prefs
, ifName
);
4388 return _SCNetworkInterfaceForceConfigurationRefresh(ifName
);
4393 SCNetworkInterfaceRefreshConfiguration(CFStringRef ifName
)
4395 return _SCNetworkInterfaceForceConfigurationRefresh(ifName
);
4400 #pragma mark SCNetworkInterface Password APIs
4404 getPasswordID(CFDictionaryRef config
, CFStringRef serviceID
)
4406 CFStringRef unique_id
= NULL
;
4408 if (config
!= NULL
) {
4409 CFStringRef encryption
;
4411 encryption
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPasswordEncryption
);
4412 if (isA_CFString(encryption
) &&
4413 CFEqual(encryption
, kSCValNetPPPAuthPasswordEncryptionKeychain
)) {
4414 unique_id
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPassword
);
4417 if (unique_id
== NULL
) {
4418 unique_id
= serviceID
;
4426 copySharedSecretID(CFDictionaryRef config
, CFStringRef serviceID
)
4428 CFMutableStringRef shared_id
= NULL
;
4430 if (config
!= NULL
) {
4431 CFStringRef encryption
;
4433 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecretEncryption
);
4434 if (isA_CFString(encryption
) &&
4435 CFEqual(encryption
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) {
4436 shared_id
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecret
);
4437 if (shared_id
!= NULL
) {
4438 CFRetain(shared_id
);
4443 if (shared_id
== NULL
) {
4444 CFStringRef unique_id
;
4446 unique_id
= getPasswordID(config
, serviceID
);
4447 shared_id
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
4448 CFStringAppend(shared_id
, CFSTR(".SS"));
4456 copyXAuthID(CFDictionaryRef config
, CFStringRef serviceID
)
4458 CFMutableStringRef xauth_id
= NULL
;
4460 if (config
!= NULL
) {
4461 CFStringRef encryption
;
4463 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPasswordEncryption
);
4464 if (isA_CFString(encryption
) &&
4465 CFEqual(encryption
, kSCValNetIPSecXAuthPasswordEncryptionKeychain
)) {
4466 xauth_id
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPassword
);
4467 if (xauth_id
!= NULL
) {
4473 if (xauth_id
== NULL
) {
4474 CFStringRef unique_id
;
4476 unique_id
= getPasswordID(config
, serviceID
);
4477 xauth_id
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
4478 CFStringAppend(xauth_id
, CFSTR(".XAUTH"));
4486 checkInterfacePassword(SCNetworkInterfaceRef interface
,
4487 SCNetworkInterfacePasswordType passwordType
,
4488 SCPreferencesRef
*prefs
,
4489 CFStringRef
*serviceID
)
4491 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4493 if (!isA_SCNetworkInterface(interface
)) {
4497 *serviceID
= interfacePrivate
->serviceID
;
4498 if (*serviceID
== NULL
) {
4502 *prefs
= interfacePrivate
->prefs
;
4503 if (*prefs
== NULL
) {
4507 switch (passwordType
) {
4508 case kSCNetworkInterfacePasswordTypePPP
: {
4509 CFStringRef interfaceType
;
4511 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
4512 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
4520 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
4521 CFStringRef interfaceType
;
4523 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
4524 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
4525 interface
= SCNetworkInterfaceGetInterface(interface
);
4526 if (interface
!= NULL
) {
4527 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
4528 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
4529 // if PPP->L2TP interface
4533 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
4534 // if IPSec interface
4541 case kSCNetworkInterfacePasswordTypeEAPOL
: {
4545 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
4546 CFStringRef interfaceType
;
4548 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
4549 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
4550 // if IPSec interface
4565 _SCErrorSet(kSCStatusInvalidArgument
);
4571 SCNetworkInterfaceCheckPassword(SCNetworkInterfaceRef interface
,
4572 SCNetworkInterfacePasswordType passwordType
)
4574 Boolean exists
= FALSE
;
4575 SCPreferencesRef prefs
= NULL
;
4576 CFStringRef serviceID
= NULL
;
4578 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
4582 switch (passwordType
) {
4583 case kSCNetworkInterfacePasswordTypePPP
: {
4584 CFDictionaryRef config
;
4585 CFStringRef unique_id
;
4587 // get configuration
4588 config
= SCNetworkInterfaceGetConfiguration(interface
);
4591 unique_id
= getPasswordID(config
, serviceID
);
4594 exists
= __extract_password(prefs
,
4596 kSCPropNetPPPAuthPassword
,
4597 kSCPropNetPPPAuthPasswordEncryption
,
4598 kSCValNetPPPAuthPasswordEncryptionKeychain
,
4604 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
4605 CFDictionaryRef config
;
4607 CFStringRef shared_id
;
4609 // get configuration
4610 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
4612 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
4614 config
= SCNetworkInterfaceGetConfiguration(interface
);
4617 // get sharedSecret ID
4618 shared_id
= copySharedSecretID(config
, serviceID
);
4621 exists
= __extract_password(prefs
,
4623 kSCPropNetIPSecSharedSecret
,
4624 kSCPropNetIPSecSharedSecretEncryption
,
4625 kSCValNetIPSecSharedSecretEncryptionKeychain
,
4628 CFRelease(shared_id
);
4632 case kSCNetworkInterfacePasswordTypeEAPOL
: {
4633 CFDictionaryRef config
;
4634 CFStringRef unique_id
= NULL
;
4636 // get configuration
4637 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
4639 // get 802.1X identifier
4640 if (config
!= NULL
) {
4641 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
4643 if (!isA_CFString(unique_id
)) {
4648 exists
= _SCPreferencesSystemKeychainPasswordItemExists(prefs
, unique_id
);
4652 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
4653 CFDictionaryRef config
;
4654 CFStringRef xauth_id
;
4656 // get configuration
4657 config
= SCNetworkInterfaceGetConfiguration(interface
);
4660 xauth_id
= copyXAuthID(config
, serviceID
);
4663 exists
= __extract_password(prefs
,
4665 kSCPropNetIPSecXAuthPassword
,
4666 kSCPropNetIPSecXAuthPasswordEncryption
,
4667 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
4670 CFRelease(xauth_id
);
4675 _SCErrorSet(kSCStatusInvalidArgument
);
4684 SCNetworkInterfaceCopyPassword(SCNetworkInterfaceRef interface
,
4685 SCNetworkInterfacePasswordType passwordType
)
4687 CFDataRef password
= NULL
;
4688 SCPreferencesRef prefs
= NULL
;
4689 CFStringRef serviceID
= NULL
;
4691 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
4695 switch (passwordType
) {
4696 case kSCNetworkInterfacePasswordTypePPP
: {
4697 CFDictionaryRef config
;
4698 CFStringRef unique_id
;
4700 // get configuration
4701 config
= SCNetworkInterfaceGetConfiguration(interface
);
4704 unique_id
= getPasswordID(config
, serviceID
);
4707 (void) __extract_password(prefs
,
4709 kSCPropNetPPPAuthPassword
,
4710 kSCPropNetPPPAuthPasswordEncryption
,
4711 kSCValNetPPPAuthPasswordEncryptionKeychain
,
4717 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
4718 CFDictionaryRef config
;
4720 CFStringRef shared_id
;
4722 // get configuration
4723 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
4725 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
4727 config
= SCNetworkInterfaceGetConfiguration(interface
);
4730 // get sharedSecret ID
4731 shared_id
= copySharedSecretID(config
, serviceID
);
4734 (void) __extract_password(prefs
,
4736 kSCPropNetIPSecSharedSecret
,
4737 kSCPropNetIPSecSharedSecretEncryption
,
4738 kSCValNetIPSecSharedSecretEncryptionKeychain
,
4742 CFRelease(shared_id
);
4746 case kSCNetworkInterfacePasswordTypeEAPOL
: {
4747 CFDictionaryRef config
;
4748 CFStringRef unique_id
= NULL
;
4750 // get configuration
4751 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
4753 // get 802.1X identifier
4754 if (config
!= NULL
) {
4755 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
4757 if (!isA_CFString(unique_id
)) {
4758 _SCErrorSet(kSCStatusFailed
);
4763 password
= _SCPreferencesSystemKeychainPasswordItemCopy(prefs
, unique_id
);
4767 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
4768 CFDictionaryRef config
;
4769 CFStringRef xauth_id
;
4771 // get configuration
4772 config
= SCNetworkInterfaceGetConfiguration(interface
);
4775 xauth_id
= copyXAuthID(config
, serviceID
);
4778 (void) __extract_password(prefs
,
4780 kSCPropNetIPSecXAuthPassword
,
4781 kSCPropNetIPSecXAuthPasswordEncryption
,
4782 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
4785 CFRelease(xauth_id
);
4790 _SCErrorSet(kSCStatusInvalidArgument
);
4799 SCNetworkInterfaceRemovePassword(SCNetworkInterfaceRef interface
,
4800 SCNetworkInterfacePasswordType passwordType
)
4803 SCPreferencesRef prefs
= NULL
;
4804 CFStringRef serviceID
= NULL
;
4806 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
4810 switch (passwordType
) {
4811 case kSCNetworkInterfacePasswordTypePPP
: {
4812 CFDictionaryRef config
;
4813 CFDictionaryRef newConfig
= NULL
;
4814 CFStringRef unique_id
;
4816 // get configuration
4817 config
= SCNetworkInterfaceGetConfiguration(interface
);
4820 unique_id
= getPasswordID(config
, serviceID
);
4823 ok
= __remove_password(prefs
,
4825 kSCPropNetPPPAuthPassword
,
4826 kSCPropNetPPPAuthPasswordEncryption
,
4827 kSCValNetPPPAuthPasswordEncryptionKeychain
,
4831 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
4832 if (newConfig
!= NULL
) CFRelease(newConfig
);
4838 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
4839 CFDictionaryRef config
;
4841 CFDictionaryRef newConfig
= NULL
;
4842 CFStringRef shared_id
;
4844 // get configuration
4845 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
4847 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
4849 config
= SCNetworkInterfaceGetConfiguration(interface
);
4852 // get sharedSecret ID
4853 shared_id
= copySharedSecretID(config
, serviceID
);
4856 ok
= __remove_password(prefs
,
4858 kSCPropNetIPSecSharedSecret
,
4859 kSCPropNetIPSecSharedSecretEncryption
,
4860 kSCValNetIPSecSharedSecretEncryptionKeychain
,
4865 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
4869 ok
= SCNetworkInterfaceSetConfiguration(interface
,
4872 if (newConfig
!= NULL
) CFRelease(newConfig
);
4875 CFRelease(shared_id
);
4879 case kSCNetworkInterfacePasswordTypeEAPOL
: {
4880 CFDictionaryRef config
;
4881 CFStringRef unique_id
= NULL
;
4883 // get configuration
4884 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
4886 // get 802.1X identifier
4887 if (config
!= NULL
) {
4888 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
4890 if (!isA_CFString(unique_id
)) {
4891 _SCErrorSet(kSCStatusFailed
);
4896 ok
= _SCPreferencesSystemKeychainPasswordItemRemove(prefs
, unique_id
);
4900 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
4901 CFDictionaryRef config
;
4902 CFDictionaryRef newConfig
= NULL
;
4903 CFStringRef xauth_id
;
4905 // get configuration
4906 config
= SCNetworkInterfaceGetConfiguration(interface
);
4909 xauth_id
= copyXAuthID(config
, serviceID
);
4912 ok
= __remove_password(prefs
,
4914 kSCPropNetIPSecXAuthPassword
,
4915 kSCPropNetIPSecXAuthPasswordEncryption
,
4916 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
4920 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
4921 if (newConfig
!= NULL
) CFRelease(newConfig
);
4924 CFRelease(xauth_id
);
4929 _SCErrorSet(kSCStatusInvalidArgument
);
4938 SCNetworkInterfaceSetPassword(SCNetworkInterfaceRef interface
,
4939 SCNetworkInterfacePasswordType passwordType
,
4941 CFDictionaryRef options
)
4943 CFStringRef account
= NULL
;
4944 CFDictionaryRef config
;
4945 CFStringRef description
= NULL
;
4946 CFStringRef label
= NULL
;
4948 SCPreferencesRef prefs
= NULL
;
4949 CFStringRef serviceID
= NULL
;
4951 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
4955 switch (passwordType
) {
4956 case kSCNetworkInterfacePasswordTypePPP
: {
4957 SCNetworkServiceRef service
= NULL
;
4958 CFStringRef unique_id
;
4960 // get configuration
4961 config
= SCNetworkInterfaceGetConfiguration(interface
);
4964 unique_id
= getPasswordID(config
, serviceID
);
4966 // get "Account", "Name", "Kind"
4967 if (config
!= NULL
) {
4968 // auth name --> keychain "Account"
4969 account
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthName
);
4971 // PPP [user defined] "name" --> keychain "Name"
4972 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
4975 if (label
== NULL
) {
4976 // service name --> keychain "Name"
4977 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
4982 label
= SCNetworkServiceGetName(service
);
4983 if (label
== NULL
) {
4984 // interface name --> keychain "Name"
4985 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
4989 if (bundle
!= NULL
) {
4990 // "PPP Password" --> keychain "Kind"
4991 description
= CFBundleCopyLocalizedString(bundle
,
4992 CFSTR("KEYCHAIN_KIND_PPP_PASSWORD"),
4993 CFSTR("PPP Password"),
4998 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
5000 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
5001 (description
!= NULL
) ? description
: CFSTR("PPP Password"),
5006 CFMutableDictionaryRef newConfig
;
5008 if (config
!= NULL
) {
5009 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
5011 newConfig
= CFDictionaryCreateMutable(NULL
,
5013 &kCFTypeDictionaryKeyCallBacks
,
5014 &kCFTypeDictionaryValueCallBacks
);
5016 CFDictionarySetValue(newConfig
,
5017 kSCPropNetPPPAuthPassword
,
5019 CFDictionarySetValue(newConfig
,
5020 kSCPropNetPPPAuthPasswordEncryption
,
5021 kSCValNetPPPAuthPasswordEncryptionKeychain
);
5022 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
5023 CFRelease(newConfig
);
5026 if (description
!= NULL
) CFRelease(description
);
5027 if (service
!= NULL
) CFRelease(service
);
5031 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
5032 CFDictionaryRef baseConfig
= NULL
;
5034 SCNetworkServiceRef service
= NULL
;
5035 CFStringRef shared_id
;
5037 // get configuration
5038 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
5039 config
= SCNetworkInterfaceGetConfiguration(interface
);
5041 baseConfig
= config
;
5042 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
5045 // get sharedSecret ID
5046 shared_id
= copySharedSecretID(config
, serviceID
);
5048 // get "Account", "Name", "Kind"
5049 if (config
!= NULL
) {
5050 CFStringRef localIdentifier
;
5051 CFStringRef localIdentifierType
;
5053 if (CFDictionaryGetValueIfPresent(config
,
5054 kSCPropNetIPSecLocalIdentifierType
,
5055 (const void **)&localIdentifierType
)
5056 && CFEqual(localIdentifierType
, kSCValNetIPSecLocalIdentifierTypeKeyID
)
5057 && CFDictionaryGetValueIfPresent(config
,
5058 kSCPropNetIPSecLocalIdentifier
,
5059 (const void **)&localIdentifier
)
5060 && isA_CFString(localIdentifier
)) {
5061 // local identifier --> keychain "Account"
5062 account
= localIdentifier
;
5065 // PPP [user defined] "name" --> keychain "Name"
5067 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
5069 if (baseConfig
!= NULL
) {
5070 label
= CFDictionaryGetValue(baseConfig
, kSCPropUserDefinedName
);
5075 if (label
== NULL
) {
5076 // service name --> keychain "Name"
5077 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
5082 label
= SCNetworkServiceGetName(service
);
5083 if (label
== NULL
) {
5084 // interface name --> keychain "Name"
5085 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
5089 if (bundle
!= NULL
) {
5090 // "IPSec Shared Secret" --> keychain "Kind"
5091 description
= CFBundleCopyLocalizedString(bundle
,
5092 CFSTR("KEYCHAIN_KIND_IPSEC_SHARED_SECRET"),
5093 CFSTR("IPSec Shared Secret"),
5098 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
5100 (label
!= NULL
) ? label
: CFSTR("VPN Connection"),
5101 (description
!= NULL
) ? description
: CFSTR("IPSec Shared Secret"),
5106 CFMutableDictionaryRef newConfig
= NULL
;
5108 if (config
!= NULL
) {
5109 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
5111 newConfig
= CFDictionaryCreateMutable(NULL
,
5113 &kCFTypeDictionaryKeyCallBacks
,
5114 &kCFTypeDictionaryValueCallBacks
);
5116 CFDictionarySetValue(newConfig
,
5117 kSCPropNetIPSecSharedSecret
,
5119 CFDictionarySetValue(newConfig
,
5120 kSCPropNetIPSecSharedSecretEncryption
,
5121 kSCValNetIPSecSharedSecretEncryptionKeychain
);
5123 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
5127 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
5129 CFRelease(newConfig
);
5132 if (description
!= NULL
) CFRelease(description
);
5133 if (service
!= NULL
) CFRelease(service
);
5134 CFRelease(shared_id
);
5138 case kSCNetworkInterfacePasswordTypeEAPOL
: {
5139 CFStringRef account
= NULL
;
5140 CFStringRef unique_id
= NULL
;
5142 // get configuration
5143 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
5145 // get 802.1X identifier
5146 if (config
!= NULL
) {
5147 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
5149 if (isA_CFString(unique_id
)) {
5150 CFRetain(unique_id
);
5154 uuid
= CFUUIDCreate(NULL
);
5155 unique_id
= CFUUIDCreateString(NULL
, uuid
);
5159 // 802.1x UserName --> keychain "Account"
5160 if (config
!= NULL
) {
5161 account
= CFDictionaryGetValue(config
, kEAPClientPropUserName
);
5164 // get "Name", "Kind"
5165 if (bundle
!= NULL
) {
5166 CFStringRef interface_name
;
5168 // "Network Connection (%@)" --> keychain "Name"
5169 interface_name
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
5170 if (interface_name
!= NULL
) {
5171 CFStringRef label_fmt
;
5173 label_fmt
= CFBundleCopyLocalizedString(bundle
,
5174 CFSTR("KEYCHAIN_DESCRIPTION_EAPOL_INTERFACE"),
5175 CFSTR("Network Connection (%@)"),
5177 label
= CFStringCreateWithFormat(NULL
, NULL
, label_fmt
, interface_name
);
5178 CFRelease(label_fmt
);
5180 label
= CFBundleCopyLocalizedString(bundle
,
5181 CFSTR("KEYCHAIN_DESCRIPTION_EAPOL"),
5182 CFSTR("Network Connection"),
5186 // "802.1X Password" --> keychain "Kind"
5187 description
= CFBundleCopyLocalizedString(bundle
,
5188 CFSTR("KEYCHAIN_KIND_EAPOL"),
5189 CFSTR("802.1X Password"),
5194 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
5196 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
5197 (description
!= NULL
) ? description
: CFSTR("802.1X Password"),
5202 CFMutableDictionaryRef newConfig
= NULL
;
5204 if (config
!= NULL
) {
5205 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
5207 newConfig
= CFDictionaryCreateMutable(NULL
,
5209 &kCFTypeDictionaryKeyCallBacks
,
5210 &kCFTypeDictionaryValueCallBacks
);
5212 CFDictionarySetValue(newConfig
,
5213 kEAPClientPropUserPasswordKeychainItemID
,
5215 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
5218 CFRelease(newConfig
);
5221 CFRelease(unique_id
);
5222 if (label
!= NULL
) CFRelease(label
);
5223 if (description
!= NULL
) CFRelease(description
);
5227 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
5228 SCNetworkServiceRef service
= NULL
;
5229 CFStringRef xauth_id
;
5231 // get configuration
5232 config
= SCNetworkInterfaceGetConfiguration(interface
);
5235 xauth_id
= copyXAuthID(config
, serviceID
);
5237 // get "Account", "Name", "Kind"
5238 if (config
!= NULL
) {
5239 // auth name --> keychain "Account"
5240 account
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthName
);
5242 // IPSec [user defined] "name" --> keychain "Name"
5243 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
5246 if (label
== NULL
) {
5247 // service name --> keychain "Name"
5248 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
5253 label
= SCNetworkServiceGetName(service
);
5254 if (label
== NULL
) {
5255 // interface name --> keychain "Name"
5256 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
5260 if (bundle
!= NULL
) {
5261 // "IPSec XAuth Password" --> keychain "Kind"
5262 description
= CFBundleCopyLocalizedString(bundle
,
5263 CFSTR("KEYCHAIN_KIND_IPSEC_XAUTH_PASSWORD"),
5264 CFSTR("IPSec XAuth Password"),
5269 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
5271 (label
!= NULL
) ? label
: CFSTR("VPN Connection"),
5272 (description
!= NULL
) ? description
: CFSTR("IPSec XAuth Password"),
5277 CFMutableDictionaryRef newConfig
;
5279 if (config
!= NULL
) {
5280 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
5282 newConfig
= CFDictionaryCreateMutable(NULL
,
5284 &kCFTypeDictionaryKeyCallBacks
,
5285 &kCFTypeDictionaryValueCallBacks
);
5287 CFDictionarySetValue(newConfig
,
5288 kSCPropNetIPSecXAuthPassword
,
5290 CFDictionarySetValue(newConfig
,
5291 kSCPropNetIPSecXAuthPasswordEncryption
,
5292 kSCValNetIPSecXAuthPasswordEncryptionKeychain
);
5293 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
5294 CFRelease(newConfig
);
5297 CFRelease(xauth_id
);
5298 if (description
!= NULL
) CFRelease(description
);
5299 if (service
!= NULL
) CFRelease(service
);
5304 _SCErrorSet(kSCStatusInvalidArgument
);
5313 #pragma mark SCNetworkInterface [InterfaceNamer] SPIs
5317 _SCNetworkInterfaceCopyInterfaceInfo(SCNetworkInterfaceRef interface
)
5319 CFMutableDictionaryRef info
;
5320 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5323 info
= CFDictionaryCreateMutable(NULL
,
5325 &kCFTypeDictionaryKeyCallBacks
,
5326 &kCFTypeDictionaryValueCallBacks
);
5328 // add non-localized interface name
5329 name
= __SCNetworkInterfaceGetNonLocalizedDisplayName(interface
);
5331 CFDictionaryAddValue(info
, kSCPropUserDefinedName
, name
);
5335 if ((interfacePrivate
->usb
.vid
!= NULL
) || (interfacePrivate
->usb
.pid
!= NULL
)) {
5336 if (interfacePrivate
->usb
.name
!= NULL
) {
5337 CFDictionaryAddValue(info
, CFSTR(kUSBProductString
), interfacePrivate
->usb
.name
);
5339 if (interfacePrivate
->usb
.vid
!= NULL
) {
5340 CFDictionaryAddValue(info
, CFSTR(kUSBVendorID
), interfacePrivate
->usb
.vid
);
5342 if (interfacePrivate
->usb
.pid
!= NULL
) {
5343 CFDictionaryAddValue(info
, CFSTR(kUSBProductID
), interfacePrivate
->usb
.pid
);
5347 if (CFDictionaryGetCount(info
) == 0) {
5348 // do not return an empty dictionary
5357 SCNetworkInterfaceRef
5358 _SCNetworkInterfaceCreateWithIONetworkInterfaceObject(io_object_t if_obj
)
5360 SCNetworkInterfaceRef interface
= NULL
;
5362 /* initialize runtime */
5363 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5365 if (IOObjectConformsTo(if_obj
, kIONetworkInterfaceClass
)) {
5366 interface
= createInterface(if_obj
, processNetworkInterface
);
5367 } else if (IOObjectConformsTo(if_obj
, kIOSerialBSDServiceValue
)) {
5368 interface
= createInterface(if_obj
, processSerialInterface
);
5376 _SCNetworkInterfaceGetConfigurationAction(SCNetworkInterfaceRef interface
)
5378 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5380 return interfacePrivate
->configurationAction
;
5385 _SCNetworkInterfaceGetHardwareAddress(SCNetworkInterfaceRef interface
)
5387 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5389 return interfacePrivate
->address
;
5394 _SCNetworkInterfaceGetIOInterfaceType(SCNetworkInterfaceRef interface
)
5396 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5398 return interfacePrivate
->type
;
5403 _SCNetworkInterfaceGetIOInterfaceUnit(SCNetworkInterfaceRef interface
)
5405 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5407 return interfacePrivate
->unit
;
5412 _SCNetworkInterfaceGetIOPath(SCNetworkInterfaceRef interface
)
5414 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5416 return interfacePrivate
->path
;
5421 _SCNetworkInterfaceIsBuiltin(SCNetworkInterfaceRef interface
)
5423 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5425 return interfacePrivate
->builtin
;
5430 #pragma mark SCNetworkInterface SPIs
5434 _SCNetworkInterfaceCopySlashDevPath(SCNetworkInterfaceRef interface
)
5436 io_registry_entry_t device
;
5437 io_iterator_t device_iterator
= MACH_PORT_NULL
;
5438 CFStringRef device_path
= NULL
;
5439 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5441 CFStringRef match_keys
[2];
5442 CFTypeRef match_vals
[2];
5443 CFDictionaryRef match_dict
;
5444 CFDictionaryRef matching
;
5446 if (interfacePrivate
->entity_device
== NULL
) {
5450 if (interfacePrivate
->entity_device_unique
== NULL
) {
5454 match_keys
[0] = CFSTR(kIOTTYBaseNameKey
);
5455 match_vals
[0] = interfacePrivate
->entity_device
;
5456 match_dict
= CFDictionaryCreate(NULL
,
5457 (const void **)match_keys
,
5458 (const void **)match_vals
,
5460 &kCFTypeDictionaryKeyCallBacks
,
5461 &kCFTypeDictionaryValueCallBacks
);
5463 match_keys
[0] = CFSTR(kIOProviderClassKey
);
5464 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
5465 match_keys
[1] = CFSTR(kIOPropertyMatchKey
);
5466 match_vals
[1] = match_dict
;
5467 matching
= CFDictionaryCreate(NULL
,
5468 (const void **)match_keys
,
5469 (const void **)match_vals
,
5470 sizeof(match_keys
)/sizeof(match_keys
[0]),
5471 &kCFTypeDictionaryKeyCallBacks
,
5472 &kCFTypeDictionaryValueCallBacks
);
5473 CFRelease(match_dict
);
5475 // note: this "matching" dictionary will be consumed by the call to IOServiceGetMatchingServices
5476 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &device_iterator
);
5477 if (kr
!= kIOReturnSuccess
) {
5478 SCLog(TRUE
, LOG_DEBUG
, CFSTR("IOServiceGetMatchingServices() failed, kr = 0x%x"), kr
);
5482 while ((device_path
== NULL
) &&
5483 ((device
= IOIteratorNext(device_iterator
)) != MACH_PORT_NULL
)) {
5484 CFDictionaryRef overrides
;
5486 overrides
= IORegistryEntrySearchCFProperty(device
,
5488 CFSTR("DeviceModemOverrides"),
5490 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
5491 if (overrides
!= NULL
) {
5492 if (isA_CFDictionary(overrides
)) {
5493 CFStringRef matchIdentifier
;
5495 matchIdentifier
= CFDictionaryGetValue(overrides
, CFSTR("UniqueIdentifier"));
5496 if (isA_CFString(matchIdentifier
) &&
5497 CFEqual(interfacePrivate
->entity_device_unique
, matchIdentifier
)) {
5498 device_path
= IORegistryEntryCreateCFProperty(device
,
5499 CFSTR(kIOTTYDeviceKey
),
5504 CFRelease(overrides
);
5506 IOObjectRelease(device
);
5509 IOObjectRelease(device_iterator
);
5513 if (device_path
== NULL
) {
5514 // if we haven't found an exact match to our UniqueIdentifier
5515 // so we simply return the base name.
5516 device_path
= SCNetworkInterfaceGetBSDName(interface
);
5517 if (device_path
!= NULL
) {
5518 CFRetain(device_path
);
5527 _SCNetworkInterfaceIsBluetoothPAN(SCNetworkInterfaceRef interface
)
5529 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5531 return (interfacePrivate
->sort_order
== kSortBluetoothPAN
);
5536 _SCNetworkInterfaceIsModemV92(SCNetworkInterfaceRef interface
)
5538 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5540 return interfacePrivate
->modemIsV92
;
5545 _SCNetworkInterfaceIsTethered(SCNetworkInterfaceRef interface
)
5547 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5549 return (interfacePrivate
->sort_order
== kSortTethered
);
5554 #pragma mark SCNetworkInterface [internal] SPIs
5558 SCNetworkInterfacePrivateRef
5559 __SCNetworkInterfaceCreateCopy(CFAllocatorRef allocator
,
5560 SCNetworkInterfaceRef interface
,
5561 SCPreferencesRef prefs
,
5562 CFStringRef serviceID
)
5564 SCNetworkInterfacePrivateRef oldPrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5565 SCNetworkInterfacePrivateRef newPrivate
;
5567 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5568 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5570 if (interface
== kSCNetworkInterfaceIPv4
) {
5571 return (SCNetworkInterfacePrivateRef
)CFRetain(interface
);
5574 newPrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, prefs
, serviceID
, NULL
);
5575 newPrivate
->interface_type
= oldPrivate
->interface_type
;
5576 if (oldPrivate
->interface
!= NULL
) {
5577 newPrivate
->interface
= (SCNetworkInterfaceRef
)__SCNetworkInterfaceCreateCopy(NULL
, // allocator
5578 oldPrivate
->interface
, // interface
5579 prefs
, // [new] prefs
5580 serviceID
); // [new] serviceID
5582 if (oldPrivate
->name
!= NULL
) {
5583 newPrivate
->name
= CFRetain(oldPrivate
->name
);
5585 if (oldPrivate
->localized_name
!= NULL
) {
5586 newPrivate
->localized_name
= CFRetain(oldPrivate
->localized_name
);
5588 newPrivate
->localized_key
= oldPrivate
->localized_key
;
5589 if (oldPrivate
->localized_arg1
!= NULL
) {
5590 newPrivate
->localized_arg1
= CFRetain(oldPrivate
->localized_arg1
);
5592 if (oldPrivate
->localized_arg2
!= NULL
) {
5593 newPrivate
->localized_arg2
= CFRetain(oldPrivate
->localized_arg2
);
5595 if (oldPrivate
->unsaved
!= NULL
) {
5596 newPrivate
->unsaved
= CFDictionaryCreateMutableCopy(NULL
, 0, oldPrivate
->unsaved
);
5598 if (oldPrivate
->entity_device
!= NULL
) {
5599 newPrivate
->entity_device
= CFRetain(oldPrivate
->entity_device
);
5601 if (oldPrivate
->entity_device_unique
!= NULL
) {
5602 newPrivate
->entity_device_unique
= CFRetain(oldPrivate
->entity_device_unique
);
5604 newPrivate
->entity_type
= oldPrivate
->entity_type
;
5605 newPrivate
->entity_subtype
= oldPrivate
->entity_subtype
;
5606 if (oldPrivate
->supported_interface_types
!= NULL
) {
5607 newPrivate
->supported_interface_types
= CFArrayCreateMutableCopy(NULL
, 0, oldPrivate
->supported_interface_types
);
5609 if (oldPrivate
->supported_protocol_types
!= NULL
) {
5610 newPrivate
->supported_protocol_types
= CFArrayCreateMutableCopy(NULL
, 0, oldPrivate
->supported_protocol_types
);
5612 if (oldPrivate
->address
!= NULL
) {
5613 newPrivate
->address
= CFRetain(oldPrivate
->address
);
5615 newPrivate
->builtin
= oldPrivate
->builtin
;
5616 if (oldPrivate
->configurationAction
!= NULL
) {
5617 newPrivate
->configurationAction
= CFRetain(oldPrivate
->configurationAction
);
5619 if (oldPrivate
->location
!= NULL
) {
5620 newPrivate
->location
= CFRetain(oldPrivate
->location
);
5622 if (oldPrivate
->path
!= NULL
) {
5623 newPrivate
->path
= CFRetain(oldPrivate
->path
);
5625 if (oldPrivate
->overrides
!= NULL
) {
5626 newPrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, oldPrivate
->overrides
);
5628 newPrivate
->modemIsV92
= oldPrivate
->modemIsV92
;
5629 if (oldPrivate
->type
!= NULL
) {
5630 newPrivate
->type
= CFRetain(oldPrivate
->type
);
5632 if (oldPrivate
->unit
!= NULL
) {
5633 newPrivate
->unit
= CFRetain(oldPrivate
->unit
);
5635 if (oldPrivate
->usb
.name
!= NULL
) {
5636 newPrivate
->usb
.name
= CFRetain(oldPrivate
->usb
.name
);
5638 if (oldPrivate
->usb
.vid
!= NULL
) {
5639 newPrivate
->usb
.vid
= CFRetain(oldPrivate
->usb
.vid
);
5641 if (oldPrivate
->usb
.pid
!= NULL
) {
5642 newPrivate
->usb
.pid
= CFRetain(oldPrivate
->usb
.pid
);
5644 newPrivate
->sort_order
= oldPrivate
->sort_order
;
5645 #if !TARGET_OS_IPHONE
5646 newPrivate
->supportsBond
= oldPrivate
->supportsBond
;
5647 if (oldPrivate
->bond
.interfaces
!= NULL
) {
5648 newPrivate
->bond
.interfaces
= CFRetain(oldPrivate
->bond
.interfaces
);
5650 if (oldPrivate
->bond
.mode
!= NULL
) {
5651 newPrivate
->bond
.mode
= CFRetain(oldPrivate
->bond
.mode
);
5653 if (oldPrivate
->bond
.options
!= NULL
) {
5654 newPrivate
->bond
.options
= CFRetain(oldPrivate
->bond
.options
);
5656 newPrivate
->supportsVLAN
= oldPrivate
->supportsVLAN
;
5657 if (oldPrivate
->vlan
.interface
!= NULL
) {
5658 newPrivate
->vlan
.interface
= CFRetain(oldPrivate
->vlan
.interface
);
5660 if (oldPrivate
->vlan
.tag
!= NULL
) {
5661 newPrivate
->vlan
.tag
= CFRetain(oldPrivate
->vlan
.tag
);
5663 if (oldPrivate
->vlan
.options
!= NULL
) {
5664 newPrivate
->vlan
.options
= CFRetain(oldPrivate
->vlan
.options
);
5666 #endif // !TARGET_OS_IPHONE
5674 __SCNetworkInterfaceCopyDeepConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
)
5676 CFMutableArrayRef configs
;
5678 configs
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
5680 while (interface
!= NULL
) {
5681 CFStringRef defaultType
;
5682 CFMutableDictionaryRef interfaceConfiguration
;
5684 interfaceConfiguration
= CFDictionaryCreateMutable(NULL
,
5686 &kCFTypeDictionaryKeyCallBacks
,
5687 &kCFTypeDictionaryValueCallBacks
);
5689 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5690 if (defaultType
!= NULL
) {
5691 CFDictionaryRef config
;
5692 CFArrayRef extendedTypes
;
5695 config
= __SCNetworkInterfaceGetConfiguration(interface
, defaultType
);
5697 config
= __SCNetworkInterfaceGetDefaultConfiguration(set
, interface
);
5699 if (config
== NULL
) {
5700 config
= (CFDictionaryRef
)kCFNull
;
5702 CFDictionarySetValue(interfaceConfiguration
, defaultType
, config
);
5704 extendedTypes
= extendedConfigurationTypes(interface
);
5705 if (extendedTypes
!= NULL
) {
5709 n
= CFArrayGetCount(extendedTypes
);
5710 for (i
= 0; i
< n
; i
++) {
5711 CFStringRef extendedType
;
5713 extendedType
= CFArrayGetValueAtIndex(extendedTypes
, i
);
5714 config
= __SCNetworkInterfaceGetConfiguration(interface
, extendedType
);
5715 if (config
== NULL
) {
5716 config
= (CFDictionaryRef
)kCFNull
;
5718 CFDictionarySetValue(interfaceConfiguration
, extendedType
, config
);
5721 CFRelease(extendedTypes
);
5725 CFArrayAppendValue(configs
, interfaceConfiguration
);
5726 CFRelease(interfaceConfiguration
);
5728 interface
= SCNetworkInterfaceGetInterface(interface
);
5737 __SCNetworkInterfaceSetDeepConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
, CFArrayRef configs
)
5741 for (i
= 0; interface
!= NULL
; i
++) {
5742 CFStringRef defaultType
;
5743 CFDictionaryRef interfaceConfiguration
;
5745 interfaceConfiguration
= (configs
!= NULL
) ? CFArrayGetValueAtIndex(configs
, i
) : NULL
;
5747 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5748 if (defaultType
!= NULL
) {
5749 CFDictionaryRef config
;
5750 CFArrayRef extendedTypes
;
5752 config
= (interfaceConfiguration
!= NULL
) ? CFDictionaryGetValue(interfaceConfiguration
, defaultType
)
5754 if (config
== (CFDictionaryRef
)kCFNull
) {
5758 // if service is not associated with the set
5759 if (!__SCNetworkInterfaceSetConfiguration(interface
, defaultType
, config
, TRUE
)) {
5760 SCLog(TRUE
, LOG_DEBUG
,
5761 CFSTR("__SCNetworkInterfaceSetDeepConfiguration __SCNetworkInterfaceSetConfiguration() failed, interface=%@, type=%@"),
5766 // apply default configuration to this set
5767 if (!__SCNetworkInterfaceSetDefaultConfiguration(set
, interface
, defaultType
, config
, TRUE
)) {
5768 SCLog(TRUE
, LOG_DEBUG
,
5769 CFSTR("__SCNetworkInterfaceSetDeepConfiguration __SCNetworkInterfaceSetDefaultConfiguration() failed, interface=%@, type=%@"),
5775 extendedTypes
= extendedConfigurationTypes(interface
);
5776 if (extendedTypes
!= NULL
) {
5780 n
= CFArrayGetCount(extendedTypes
);
5781 for (j
= 0; j
< n
; j
++) {
5782 CFStringRef extendedType
;
5784 extendedType
= CFArrayGetValueAtIndex(extendedTypes
, j
);
5785 config
= (interfaceConfiguration
!= NULL
) ? CFDictionaryGetValue(interfaceConfiguration
, extendedType
)
5787 if (config
== (CFDictionaryRef
)kCFNull
) {
5790 if (!__SCNetworkInterfaceSetConfiguration(interface
, extendedType
, config
, TRUE
)) {
5791 SCLog(TRUE
, LOG_DEBUG
,
5792 CFSTR("__SCNetworkInterfaceSetDeepConfiguration __SCNetworkInterfaceSetConfiguration() failed, interface=%@, type=%@"),
5798 CFRelease(extendedTypes
);
5802 interface
= SCNetworkInterfaceGetInterface(interface
);