2 * Copyright (c) 2004-2011 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"
78 #ifndef kIOUserEthernetInterfaceRoleKey
79 #define kIOUserEthernetInterfaceRoleKey "InterfaceRole"
83 #include <mach/mach.h>
85 #include <net/if_types.h>
86 #include <net/route.h>
87 #include <sys/param.h>
88 #include <sys/types.h>
89 #include <sys/socket.h>
91 #include <sys/sysctl.h>
93 #include <NSSystemDirectories.h>
96 static CFStringRef
copy_interface_string (CFBundleRef bundle
, CFStringRef key
, Boolean localized
);
97 static CFStringRef
__SCNetworkInterfaceCopyDescription (CFTypeRef cf
);
98 static void __SCNetworkInterfaceDeallocate (CFTypeRef cf
);
99 static Boolean
__SCNetworkInterfaceEqual (CFTypeRef cf1
, CFTypeRef cf2
);
100 static CFHashCode
__SCNetworkInterfaceHash (CFTypeRef cf
);
119 kSortBluetoothPAN_GN
,
120 kSortBluetoothPAN_NAP
,
129 const CFStringRef kSCNetworkInterfaceType6to4
= CFSTR("6to4");
130 const CFStringRef kSCNetworkInterfaceTypeBluetooth
= CFSTR("Bluetooth");
131 const CFStringRef kSCNetworkInterfaceTypeBond
= CFSTR("Bond");
132 const CFStringRef kSCNetworkInterfaceTypeBridge
= CFSTR("Bridge");
133 const CFStringRef kSCNetworkInterfaceTypeEthernet
= CFSTR("Ethernet");
134 const CFStringRef kSCNetworkInterfaceTypeFireWire
= CFSTR("FireWire");
135 const CFStringRef kSCNetworkInterfaceTypeIEEE80211
= CFSTR("IEEE80211"); // IEEE 802.11, AirPort
136 const CFStringRef kSCNetworkInterfaceTypeIPSec
= CFSTR("IPSec");
137 const CFStringRef kSCNetworkInterfaceTypeIrDA
= CFSTR("IrDA");
138 const CFStringRef kSCNetworkInterfaceTypeL2TP
= CFSTR("L2TP");
139 const CFStringRef kSCNetworkInterfaceTypeLoopback
= CFSTR("Loopback");
140 const CFStringRef kSCNetworkInterfaceTypeModem
= CFSTR("Modem");
141 const CFStringRef kSCNetworkInterfaceTypePPP
= CFSTR("PPP");
142 const CFStringRef kSCNetworkInterfaceTypePPTP
= CFSTR("PPTP");
143 const CFStringRef kSCNetworkInterfaceTypeSerial
= CFSTR("Serial");
144 const CFStringRef kSCNetworkInterfaceTypeVLAN
= CFSTR("VLAN");
145 const CFStringRef kSCNetworkInterfaceTypeVPN
= CFSTR("VPN");
146 const CFStringRef kSCNetworkInterfaceTypeWWAN
= CFSTR("WWAN");
148 const CFStringRef kSCNetworkInterfaceTypeIPv4
= CFSTR("IPv4");
150 static SCNetworkInterfacePrivate __kSCNetworkInterfaceIPv4
= {
151 INIT_CFRUNTIME_BASE(), // cfBase
152 NULL
, // interface type
154 NULL
, // localized name
155 NULL
, // localization key
156 NULL
, // localization arg1
157 NULL
, // localization arg2
158 NULL
, // [layered] interface
162 NULL
, // entity_device
163 NULL
, // entity_device_unique
165 NULL
, // entity_subtype
166 NULL
, // supported_interface_types
167 NULL
, // supported_protocol_types
169 NULL
, // addressString
171 NULL
, // configurationAction
179 { NULL
, 0, 0 }, // usb { name, vid, pid }
180 kSortUnknown
, // sort_order
181 FALSE
, // supportsBond
182 { NULL
, NULL
, NULL
}, // bond { interfaces, options, mode }
183 FALSE
, // supportsBridge
184 { NULL
, NULL
}, // bridge { interfaces, options }
185 FALSE
, // supportsVLAN
186 { NULL
, NULL
, NULL
} // vlan { interface, tag, options }
189 const SCNetworkInterfaceRef kSCNetworkInterfaceIPv4
= (SCNetworkInterfaceRef
)&__kSCNetworkInterfaceIPv4
;
191 static SCNetworkInterfacePrivate __kSCNetworkInterfaceLoopback
= {
192 INIT_CFRUNTIME_BASE(), // cfBase
193 NULL
, // interface type
195 NULL
, // localized name
196 NULL
, // localization key
197 NULL
, // localization arg1
198 NULL
, // localization arg2
199 NULL
, // [layered] interface
203 NULL
, // entity_device
204 NULL
, // entity_device_unique
206 NULL
, // entity_subtype
207 NULL
, // supported_interface_types
208 NULL
, // supported_protocol_types
210 NULL
, // addressString
212 NULL
, // configurationAction
220 { NULL
, 0, 0 }, // usb { name, vid, pid }
221 kSortUnknown
, // sort_order
222 FALSE
, // supportsBond
223 { NULL
, NULL
, NULL
}, // bond { interfaces, options, mode }
224 FALSE
, // supportsBridge
225 { NULL
, NULL
}, // bridge { interfaces, options }
226 FALSE
, // supportsVLAN
227 { NULL
, NULL
, NULL
} // vlan { interface, tag, options }
230 const SCNetworkInterfaceRef kSCNetworkInterfaceLoopback
= (SCNetworkInterfaceRef
)&__kSCNetworkInterfaceLoopback
;
232 static CFMutableSetRef vendor_interface_types
= NULL
;
235 #pragma mark SCNetworkInterface configuration details
244 #define doOverIP do6to4|doL2TP|doPPTP|doIPSec
249 #define doProxies 1<<4
250 #if !TARGET_OS_IPHONE
252 #else // !TARGET_OS_IPHONE
254 #endif // !TARGET_OS_IPHONE
256 static const struct {
257 const CFStringRef
*interface_type
;
258 const CFStringRef
*entity_hardware
;
259 Boolean per_interface_config
;
260 uint32_t supported_interfaces
;
261 const CFStringRef
*ppp_subtype
;
262 uint32_t supported_protocols
;
263 } configurations
[] = {
264 // interface type entity_hardware if config? interface types PPP sub-type interface protocols
265 // ===================================== ================= ========== =============== ======================================= =========================================
266 { &kSCNetworkInterfaceType6to4
, &kSCEntNet6to4
, FALSE
, doNone
, NULL
, doIPv6
},
267 { &kSCNetworkInterfaceTypeBluetooth
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
268 { &kSCNetworkInterfaceTypeBond
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
269 { &kSCNetworkInterfaceTypeBridge
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
270 { &kSCNetworkInterfaceTypeEthernet
, &kSCEntNetEthernet
, TRUE
, doPPP
, &kSCValNetInterfaceSubTypePPPoE
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
271 { &kSCNetworkInterfaceTypeFireWire
, &kSCEntNetFireWire
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
272 { &kSCNetworkInterfaceTypeIEEE80211
, &kSCEntNetAirPort
, TRUE
, doPPP
, &kSCValNetInterfaceSubTypePPPoE
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
273 { &kSCNetworkInterfaceTypeIPSec
, &kSCEntNetIPSec
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
274 { &kSCNetworkInterfaceTypeIrDA
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
275 { &kSCNetworkInterfaceTypeL2TP
, NULL
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypeL2TP
, doNone
},
276 { &kSCNetworkInterfaceTypeModem
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
277 { &kSCNetworkInterfaceTypePPP
, &kSCEntNetPPP
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
278 { &kSCNetworkInterfaceTypePPTP
, NULL
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPTP
, doNone
},
279 { &kSCNetworkInterfaceTypeSerial
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
280 { &kSCNetworkInterfaceTypeVLAN
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
281 { &kSCNetworkInterfaceTypeVPN
, &kSCEntNetVPN
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
282 { &kSCNetworkInterfaceTypeWWAN
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
283 // ===================================== ================= ========== =============== ======================================= =========================================
284 { &kSCNetworkInterfaceTypeLoopback
, NULL
, TRUE
, doNone
, NULL
, doIPv4
|doIPv6
},
285 // ===================================== ================= ========== =============== ======================================= =========================================
286 { &kSCNetworkInterfaceTypeIPv4
, NULL
, FALSE
, doOverIP
, NULL
, doNone
}
290 #define NETWORKINTERFACE_LOCALIZATIONS CFSTR("NetworkInterface")
291 static CFBundleRef bundle
= NULL
;
294 static CFTypeID __kSCNetworkInterfaceTypeID
= _kCFRuntimeNotATypeID
;
297 static const CFRuntimeClass __SCNetworkInterfaceClass
= {
299 "SCNetworkInterface", // className
302 __SCNetworkInterfaceDeallocate
, // dealloc
303 __SCNetworkInterfaceEqual
, // equal
304 __SCNetworkInterfaceHash
, // hash
305 NULL
, // copyFormattingDesc
306 __SCNetworkInterfaceCopyDescription
// copyDebugDesc
310 static pthread_once_t initialized
= PTHREAD_ONCE_INIT
;
311 static pthread_once_t iokit_quiet
= PTHREAD_ONCE_INIT
;
314 static mach_port_t masterPort
= MACH_PORT_NULL
;
318 __SCNetworkInterfaceCopyDescription(CFTypeRef cf
)
320 CFAllocatorRef allocator
= CFGetAllocator(cf
);
321 CFMutableStringRef result
;
322 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
324 result
= CFStringCreateMutable(allocator
, 0);
325 CFStringAppendFormat(result
, NULL
, CFSTR("<SCNetworkInterface %p [%p]> {"), cf
, allocator
);
326 CFStringAppendFormat(result
, NULL
, CFSTR("type = %@"), interfacePrivate
->interface_type
);
327 CFStringAppendFormat(result
, NULL
, CFSTR(", entity_device = %@"), interfacePrivate
->entity_device
);
328 if (interfacePrivate
->entity_device_unique
!= NULL
) {
329 CFStringAppendFormat(result
, NULL
, CFSTR("+%@"), interfacePrivate
->entity_device_unique
);
331 CFStringAppendFormat(result
, NULL
, CFSTR(", entity_type = %@"), interfacePrivate
->entity_type
);
332 if (interfacePrivate
->entity_subtype
!= NULL
) {
333 CFStringAppendFormat(result
, NULL
, CFSTR(" / %@"), interfacePrivate
->entity_subtype
);
335 if (interfacePrivate
->name
!= NULL
) {
336 CFStringAppendFormat(result
, NULL
, CFSTR(", name = %@"), interfacePrivate
->name
);
338 if (interfacePrivate
->localized_name
!= NULL
) {
339 CFStringAppendFormat(result
, NULL
, CFSTR(", name(l) = %@"), interfacePrivate
->localized_name
);
341 if (interfacePrivate
->localized_key
!= NULL
) {
342 CFStringAppendFormat(result
, NULL
, CFSTR(", name(k) = \"%@\""), interfacePrivate
->localized_key
);
343 if (interfacePrivate
->localized_arg1
!= NULL
) {
344 CFStringAppendFormat(result
, NULL
, CFSTR("+\"%@\""), interfacePrivate
->localized_arg1
);
346 if (interfacePrivate
->localized_arg2
!= NULL
) {
347 CFStringAppendFormat(result
, NULL
, CFSTR("+\"%@\""), interfacePrivate
->localized_arg2
);
351 if (interfacePrivate
->address
!= NULL
) {
356 CFStringAppendFormat(result
, NULL
, CFSTR(", address = 0x"));
358 data
= CFDataGetBytePtr(interfacePrivate
->address
);
359 dataLen
= CFDataGetLength(interfacePrivate
->address
);
360 for (i
= 0; i
< dataLen
; i
++) {
361 CFStringAppendFormat(result
, NULL
, CFSTR("%02x"), data
[i
]);
364 CFStringAppendFormat(result
, NULL
, CFSTR(", builtin = %s"), interfacePrivate
->builtin
? "TRUE" : "FALSE");
365 if (interfacePrivate
->hidden
) {
366 CFStringAppendFormat(result
, NULL
, CFSTR(", hidden = TRUE"));
368 if (interfacePrivate
->modemIsV92
) {
369 CFStringAppendFormat(result
, NULL
, CFSTR(", v.92"));
371 if (interfacePrivate
->location
!= NULL
) {
372 CFStringAppendFormat(result
, NULL
, CFSTR(", location = %@"), interfacePrivate
->location
);
374 if (interfacePrivate
->path
!= NULL
) {
375 CFStringAppendFormat(result
, NULL
, CFSTR(", path = %@"), interfacePrivate
->path
);
377 if (interfacePrivate
->type
!= NULL
) {
378 CFStringAppendFormat(result
, NULL
, CFSTR(", type = %@"), interfacePrivate
->type
);
380 if (interfacePrivate
->unit
!= NULL
) {
381 CFStringAppendFormat(result
, NULL
, CFSTR(", unit = %@"), interfacePrivate
->unit
);
383 if ((interfacePrivate
->usb
.vid
!= NULL
) || (interfacePrivate
->usb
.pid
!= NULL
)) {
387 if (!isA_CFNumber(interfacePrivate
->usb
.pid
) ||
388 !CFNumberGetValue(interfacePrivate
->usb
.vid
, kCFNumberIntType
, &pid
)) {
391 if (!isA_CFNumber(interfacePrivate
->usb
.vid
) ||
392 !CFNumberGetValue(interfacePrivate
->usb
.vid
, kCFNumberIntType
, &vid
)) {
396 if (interfacePrivate
->usb
.name
!= NULL
) {
397 CFStringAppendFormat(result
, NULL
, CFSTR(", USB name = %@"),
398 interfacePrivate
->usb
.name
);
401 CFStringAppendFormat(result
, NULL
, CFSTR(", USB vid/pid = 0x%0x/0x%0x"),
402 interfacePrivate
->usb
.vid
,
403 interfacePrivate
->usb
.pid
);
405 if (interfacePrivate
->configurationAction
!= NULL
) {
406 CFStringAppendFormat(result
, NULL
, CFSTR(", action = %@"), interfacePrivate
->configurationAction
);
408 if (interfacePrivate
->overrides
!= NULL
) {
409 CFStringAppendFormat(result
, NULL
, CFSTR(", overrides = %p"), interfacePrivate
->overrides
);
411 CFStringAppendFormat(result
, NULL
, CFSTR(", order = %d"), interfacePrivate
->sort_order
);
412 if (interfacePrivate
->prefs
!= NULL
) {
413 CFStringAppendFormat(result
, NULL
, CFSTR(", prefs = %p"), interfacePrivate
->prefs
);
415 if (interfacePrivate
->serviceID
!= NULL
) {
416 CFStringAppendFormat(result
, NULL
, CFSTR(", service = %@"), interfacePrivate
->serviceID
);
418 if (interfacePrivate
->interface
!= NULL
) {
419 CFStringAppendFormat(result
, NULL
, CFSTR(", interface = %@"), interfacePrivate
->interface
);
421 if (interfacePrivate
->unsaved
!= NULL
) {
422 CFStringAppendFormat(result
, NULL
, CFSTR(", unsaved = %@"), interfacePrivate
->unsaved
);
425 if (interfacePrivate
->bond
.interfaces
!= NULL
) {
429 n
= CFArrayGetCount(interfacePrivate
->bond
.interfaces
);
430 for (i
= 0; i
< n
; i
++) {
431 SCNetworkInterfaceRef member
;
433 member
= CFArrayGetValueAtIndex(interfacePrivate
->bond
.interfaces
, i
);
434 CFStringAppendFormat(result
, NULL
,
436 (i
== 0) ? ", interfaces = " : ", ",
437 SCNetworkInterfaceGetBSDName(member
));
440 if (interfacePrivate
->bond
.mode
!= NULL
) {
441 CFStringAppendFormat(result
, NULL
, CFSTR(", mode = %@"), interfacePrivate
->bond
.mode
);
443 if (interfacePrivate
->bond
.options
!= NULL
) {
444 CFStringAppendFormat(result
, NULL
, CFSTR(", options = %@"), interfacePrivate
->bond
.options
);
447 if (interfacePrivate
->bridge
.interfaces
!= NULL
) {
451 n
= CFArrayGetCount(interfacePrivate
->bridge
.interfaces
);
452 for (i
= 0; i
< n
; i
++) {
453 SCNetworkInterfaceRef member
;
455 member
= CFArrayGetValueAtIndex(interfacePrivate
->bridge
.interfaces
, i
);
456 CFStringAppendFormat(result
, NULL
,
458 (i
== 0) ? ", interfaces = " : ", ",
459 SCNetworkInterfaceGetBSDName(member
));
462 if (interfacePrivate
->bridge
.options
!= NULL
) {
463 CFStringAppendFormat(result
, NULL
, CFSTR(", options = %@"), interfacePrivate
->bridge
.options
);
466 if (interfacePrivate
->vlan
.interface
!= NULL
) {
467 CFStringAppendFormat(result
, NULL
,
468 CFSTR(", interface = %@"),
469 SCNetworkInterfaceGetBSDName(interfacePrivate
->vlan
.interface
));
471 if (interfacePrivate
->vlan
.tag
!= NULL
) {
472 CFStringAppendFormat(result
, NULL
, CFSTR(", tag = %@"), interfacePrivate
->vlan
.tag
);
474 if (interfacePrivate
->vlan
.options
!= NULL
) {
475 CFStringAppendFormat(result
, NULL
, CFSTR(", options = %@"), interfacePrivate
->vlan
.options
);
478 CFStringAppendFormat(result
, NULL
, CFSTR("}"));
485 __SCNetworkInterfaceDeallocate(CFTypeRef cf
)
487 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
489 /* release resources */
491 if (interfacePrivate
->name
!= NULL
)
492 CFRelease(interfacePrivate
->name
);
494 if (interfacePrivate
->localized_name
!= NULL
)
495 CFRelease(interfacePrivate
->localized_name
);
497 if (interfacePrivate
->localized_arg1
!= NULL
)
498 CFRelease(interfacePrivate
->localized_arg1
);
500 if (interfacePrivate
->localized_arg2
!= NULL
)
501 CFRelease(interfacePrivate
->localized_arg2
);
503 if (interfacePrivate
->interface
!= NULL
)
504 CFRelease(interfacePrivate
->interface
);
506 if (interfacePrivate
->prefs
!= NULL
)
507 CFRelease(interfacePrivate
->prefs
);
509 if (interfacePrivate
->serviceID
!= NULL
)
510 CFRelease(interfacePrivate
->serviceID
);
512 if (interfacePrivate
->unsaved
!= NULL
)
513 CFRelease(interfacePrivate
->unsaved
);
515 if (interfacePrivate
->entity_device
!= NULL
)
516 CFRelease(interfacePrivate
->entity_device
);
518 if (interfacePrivate
->entity_device_unique
!= NULL
)
519 CFRelease(interfacePrivate
->entity_device_unique
);
521 if (interfacePrivate
->supported_interface_types
!= NULL
)
522 CFRelease(interfacePrivate
->supported_interface_types
);
524 if (interfacePrivate
->supported_protocol_types
!= NULL
)
525 CFRelease(interfacePrivate
->supported_protocol_types
);
527 if (interfacePrivate
->address
!= NULL
)
528 CFRelease(interfacePrivate
->address
);
530 if (interfacePrivate
->addressString
!= NULL
)
531 CFRelease(interfacePrivate
->addressString
);
533 if (interfacePrivate
->configurationAction
!= NULL
)
534 CFRelease(interfacePrivate
->configurationAction
);
536 if (interfacePrivate
->location
!= NULL
)
537 CFRelease(interfacePrivate
->location
);
539 if (interfacePrivate
->path
!= NULL
)
540 CFRelease(interfacePrivate
->path
);
542 if (interfacePrivate
->overrides
!= NULL
)
543 CFRelease(interfacePrivate
->overrides
);
545 if (interfacePrivate
->type
!= NULL
)
546 CFRelease(interfacePrivate
->type
);
548 if (interfacePrivate
->unit
!= NULL
)
549 CFRelease(interfacePrivate
->unit
);
551 if (interfacePrivate
->usb
.name
!= NULL
)
552 CFRelease(interfacePrivate
->usb
.name
);
554 if (interfacePrivate
->usb
.pid
!= NULL
)
555 CFRelease(interfacePrivate
->usb
.pid
);
557 if (interfacePrivate
->usb
.vid
!= NULL
)
558 CFRelease(interfacePrivate
->usb
.vid
);
560 if (interfacePrivate
->bond
.interfaces
!= NULL
)
561 CFRelease(interfacePrivate
->bond
.interfaces
);
563 if (interfacePrivate
->bond
.mode
!= NULL
)
564 CFRelease(interfacePrivate
->bond
.mode
);
566 if (interfacePrivate
->bond
.options
!= NULL
)
567 CFRelease(interfacePrivate
->bond
.options
);
569 if (interfacePrivate
->bridge
.interfaces
!= NULL
)
570 CFRelease(interfacePrivate
->bridge
.interfaces
);
572 if (interfacePrivate
->bridge
.options
!= NULL
)
573 CFRelease(interfacePrivate
->bridge
.options
);
575 if (interfacePrivate
->vlan
.interface
!= NULL
)
576 CFRelease(interfacePrivate
->vlan
.interface
);
578 if (interfacePrivate
->vlan
.tag
!= NULL
)
579 CFRelease(interfacePrivate
->vlan
.tag
);
581 if (interfacePrivate
->vlan
.options
!= NULL
)
582 CFRelease(interfacePrivate
->vlan
.options
);
589 __SCNetworkInterfaceEqual(CFTypeRef cf1
, CFTypeRef cf2
)
591 SCNetworkInterfacePrivateRef if1
= (SCNetworkInterfacePrivateRef
)cf1
;
592 SCNetworkInterfacePrivateRef if2
= (SCNetworkInterfacePrivateRef
)cf2
;
597 if (!CFEqual(if1
->interface_type
, if2
->interface_type
)) {
598 return FALSE
; // if not the same interface type
601 if (!_SC_CFEqual(if1
->entity_device
, if2
->entity_device
)) {
602 return FALSE
; // if not the same device
605 if ((if1
->entity_device_unique
!= NULL
) && (if2
->entity_device_unique
!= NULL
)) {
606 if (!_SC_CFEqual(if1
->entity_device_unique
, if2
->entity_device_unique
)) {
607 return FALSE
; // if not the same device unique identifier
609 } else if ((if1
->entity_device_unique
!= NULL
) || (if2
->entity_device_unique
!= NULL
)) {
613 name1
= __SCNetworkInterfaceGetNonLocalizedDisplayName((SCNetworkInterfaceRef
)if1
);
614 name2
= __SCNetworkInterfaceGetNonLocalizedDisplayName((SCNetworkInterfaceRef
)if2
);
615 if ((name1
!= NULL
) && (name2
!= NULL
) && !_SC_CFEqual(name1
, name2
)) {
616 return FALSE
; // if same device but not the same display name
620 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeBond
)) {
621 if (!_SC_CFEqual(if1
->bond
.interfaces
, if2
->bond
.interfaces
)) {
622 return FALSE
; // if not the same interfaces
624 if (!_SC_CFEqual(if1
->bond
.mode
, if2
->bond
.mode
)) {
625 return FALSE
; // if not the same mode
629 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeBridge
)) {
630 if (!_SC_CFEqual(if1
->bridge
.interfaces
, if2
->bridge
.interfaces
)) {
631 return FALSE
; // if not the same interfaces
635 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeVLAN
)) {
636 if (!_SC_CFEqual(if1
->vlan
.interface
, if2
->vlan
.interface
)) {
637 return FALSE
; // if not the same physical interface
639 if (!_SC_CFEqual(if1
->vlan
.tag
, if2
->vlan
.tag
)) {
640 return FALSE
; // if not the same tag
644 if (!_SC_CFEqual(if1
->interface
, if2
->interface
)) {
645 return FALSE
; // if not the same layering
653 __SCNetworkInterfaceHash(CFTypeRef cf
)
656 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
658 if (interfacePrivate
->entity_device
!= NULL
) {
659 if (interfacePrivate
->entity_device_unique
== NULL
) {
660 hash
= CFHash(interfacePrivate
->entity_device
);
664 str
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@+%@"),
665 interfacePrivate
->entity_device
,
666 interfacePrivate
->entity_device_unique
);
677 __SCNetworkInterfaceInitialize(void)
682 __kSCNetworkInterfaceTypeID
= _CFRuntimeRegisterClass(&__SCNetworkInterfaceClass
);
684 // initialize __kSCNetworkInterfaceIPv4
685 _CFRuntimeInitStaticInstance(&__kSCNetworkInterfaceIPv4
, __kSCNetworkInterfaceTypeID
);
686 __kSCNetworkInterfaceIPv4
.interface_type
= kSCNetworkInterfaceTypeIPv4
;
687 __kSCNetworkInterfaceIPv4
.localized_key
= CFSTR("ipv4");
689 // initialize __kSCNetworkInterfaceLoopback
690 _CFRuntimeInitStaticInstance(&__kSCNetworkInterfaceLoopback
, __kSCNetworkInterfaceTypeID
);
691 __kSCNetworkInterfaceLoopback
.interface_type
= kSCNetworkInterfaceTypeLoopback
;
692 __kSCNetworkInterfaceLoopback
.localized_key
= CFSTR("loopback");
693 __kSCNetworkInterfaceLoopback
.entity_device
= CFRetain(CFSTR("lo0"));
694 __kSCNetworkInterfaceLoopback
.entity_type
= kSCValNetInterfaceTypeLoopback
;
696 // get CFBundleRef for SystemConfiguration.framework
697 bundle
= _SC_CFBundleGet();
699 // get mach port used to communication with IOKit
700 kr
= IOMasterPort(MACH_PORT_NULL
, &masterPort
);
701 if (kr
!= KERN_SUCCESS
) {
702 SCLog(TRUE
, LOG_DEBUG
,
703 CFSTR("__SCNetworkInterfaceInitialize(), could not get IOMasterPort, kr = 0x%x"),
712 SCNetworkInterfacePrivateRef
713 __SCNetworkInterfaceCreatePrivate(CFAllocatorRef allocator
,
714 SCNetworkInterfaceRef interface
,
715 SCPreferencesRef prefs
,
716 CFStringRef serviceID
,
719 SCNetworkInterfacePrivateRef interfacePrivate
;
722 /* initialize runtime */
723 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
725 /* allocate target */
726 size
= sizeof(SCNetworkInterfacePrivate
) - sizeof(CFRuntimeBase
);
727 interfacePrivate
= (SCNetworkInterfacePrivateRef
)_CFRuntimeCreateInstance(allocator
,
728 __kSCNetworkInterfaceTypeID
,
731 if (interfacePrivate
== NULL
) {
735 interfacePrivate
->interface_type
= NULL
;
736 interfacePrivate
->name
= NULL
;
737 interfacePrivate
->localized_name
= NULL
;
738 interfacePrivate
->localized_key
= NULL
;
739 interfacePrivate
->localized_arg1
= NULL
;
740 interfacePrivate
->localized_arg2
= NULL
;
741 interfacePrivate
->interface
= (interface
!= NULL
) ? CFRetain(interface
) : NULL
;
742 interfacePrivate
->prefs
= (prefs
!= NULL
) ? CFRetain(prefs
) : NULL
;
743 interfacePrivate
->serviceID
= (serviceID
!= NULL
) ? CFRetain(serviceID
) : NULL
;
744 interfacePrivate
->unsaved
= NULL
;
745 interfacePrivate
->entity_device
= NULL
;
746 interfacePrivate
->entity_device_unique
= NULL
;
747 interfacePrivate
->entity_type
= NULL
;
748 interfacePrivate
->entity_subtype
= NULL
;
749 interfacePrivate
->supported_interface_types
= NULL
;
750 interfacePrivate
->supported_protocol_types
= NULL
;
751 interfacePrivate
->address
= NULL
;
752 interfacePrivate
->addressString
= NULL
;
753 interfacePrivate
->builtin
= FALSE
;
754 interfacePrivate
->configurationAction
= NULL
;
755 interfacePrivate
->path
= (path
!= NULL
) ? CFStringCreateWithCString(NULL
, path
, kCFStringEncodingUTF8
)
757 interfacePrivate
->location
= NULL
;
758 interfacePrivate
->overrides
= NULL
;
759 interfacePrivate
->modemIsV92
= FALSE
;
760 interfacePrivate
->type
= NULL
;
761 interfacePrivate
->unit
= NULL
;
762 interfacePrivate
->usb
.name
= NULL
;
763 interfacePrivate
->usb
.vid
= NULL
;
764 interfacePrivate
->usb
.pid
= NULL
;
765 interfacePrivate
->sort_order
= kSortUnknown
;
767 interfacePrivate
->supportsBond
= FALSE
;
768 interfacePrivate
->bond
.interfaces
= NULL
;
769 interfacePrivate
->bond
.mode
= NULL
;
770 interfacePrivate
->bond
.options
= NULL
;
772 interfacePrivate
->supportsBridge
= FALSE
;
773 interfacePrivate
->bridge
.interfaces
= NULL
;
774 interfacePrivate
->bridge
.options
= NULL
;
776 interfacePrivate
->supportsVLAN
= FALSE
;
777 interfacePrivate
->vlan
.interface
= NULL
;
778 interfacePrivate
->vlan
.tag
= NULL
;
779 interfacePrivate
->vlan
.options
= NULL
;
781 return interfacePrivate
;
787 __SCNetworkInterfaceSupportsVLAN(CFStringRef bsd_if
)
791 struct if_msghdr
* ifm
;
792 char * if_name
= NULL
;
793 unsigned int if_index
;
795 Boolean vlanOK
= FALSE
;
797 // get the interface index
798 if_name
= _SC_cfstring_to_cstring(bsd_if
, NULL
, 0, kCFStringEncodingASCII
);
799 if (if_name
== NULL
) {
800 return FALSE
; // if conversion error
802 if_index
= if_nametoindex(if_name
);
804 goto done
; // if unknown interface
807 // get information for the specified interface
812 mib
[4] = NET_RT_IFLIST
;
813 mib
[5] = if_index
; /* ask for exactly one interface */
815 if (sysctl(mib
, 6, NULL
, &buf_len
, NULL
, 0) == -1) {
816 SCLog(TRUE
, LOG_ERR
, CFSTR("sysctl() size failed: %s"), strerror(errno
));
819 buf
= CFAllocatorAllocate(NULL
, buf_len
, 0);
820 if (sysctl(mib
, 6, buf
, &buf_len
, NULL
, 0) == -1) {
821 SCLog(TRUE
, LOG_ERR
, CFSTR("sysctl() failed: %s"), strerror(errno
));
825 // check the link type and hwassist flags
826 ifm
= (struct if_msghdr
*)buf
;
827 switch (ifm
->ifm_type
) {
829 #if defined(IF_HWASSIST_VLAN_TAGGING) && defined(IF_HWASSIST_VLAN_MTU)
830 struct if_data
*if_data
= &ifm
->ifm_data
;
832 if (if_data
->ifi_hwassist
& (IF_HWASSIST_VLAN_TAGGING
| IF_HWASSIST_VLAN_MTU
)) {
842 if (if_name
!= NULL
) CFAllocatorDeallocate(NULL
, if_name
);
843 if (buf
!= NULL
) CFAllocatorDeallocate(NULL
, buf
);
850 SCNetworkInterfacePrivateRef
851 _SCBondInterfaceCreatePrivate(CFAllocatorRef allocator
,
854 SCNetworkInterfacePrivateRef interfacePrivate
;
856 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
, NULL
);
857 if (interfacePrivate
== NULL
) {
861 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBond
;
862 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
863 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, bond_if
);
864 interfacePrivate
->builtin
= TRUE
;
865 interfacePrivate
->supportsVLAN
= __SCNetworkInterfaceSupportsVLAN(bond_if
);
866 interfacePrivate
->sort_order
= kSortBond
;
868 interfacePrivate
->localized_key
= CFSTR("bond");
869 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
871 interfacePrivate
->bond
.interfaces
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
872 // interfacePrivate->bond.mode = NULL;
873 // interfacePrivate->bond.options = NULL;
875 return interfacePrivate
;
880 SCNetworkInterfacePrivateRef
881 _SCBridgeInterfaceCreatePrivate(CFAllocatorRef allocator
,
882 CFStringRef bridge_if
)
884 SCNetworkInterfacePrivateRef interfacePrivate
;
886 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
, NULL
);
887 if (interfacePrivate
== NULL
) {
891 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBridge
;
892 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
893 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, bridge_if
);
894 interfacePrivate
->builtin
= TRUE
;
895 interfacePrivate
->supportsVLAN
= __SCNetworkInterfaceSupportsVLAN(bridge_if
);
896 interfacePrivate
->sort_order
= kSortBridge
;
898 interfacePrivate
->localized_key
= CFSTR("bridge");
899 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
901 interfacePrivate
->bridge
.interfaces
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
902 // interfacePrivate->bridge.options = NULL;
904 return interfacePrivate
;
909 SCNetworkInterfacePrivateRef
910 _SCVLANInterfaceCreatePrivate(CFAllocatorRef allocator
,
913 SCNetworkInterfacePrivateRef interfacePrivate
;
915 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
, NULL
);
916 if (interfacePrivate
== NULL
) {
920 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeVLAN
;
921 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
922 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, vlan_if
);
923 interfacePrivate
->builtin
= TRUE
;
924 interfacePrivate
->sort_order
= kSortVLAN
;
926 interfacePrivate
->localized_key
= CFSTR("vlan");
927 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
929 // interfacePrivate->vlan.interface = NULL;
930 // interfacePrivate->vlan.tag = NULL;
931 // interfacePrivate->vlan.options = NULL;
933 return interfacePrivate
;
938 #pragma mark Interface ordering
942 split_path(CFStringRef path
)
944 CFArrayRef components
;
945 CFMutableStringRef nPath
;
947 // turn '@'s into '/'s
948 nPath
= CFStringCreateMutableCopy(NULL
, 0, path
);
949 (void) CFStringFindAndReplace(nPath
,
952 CFRangeMake(0, CFStringGetLength(nPath
)),
955 // split path into components to be compared
956 components
= CFStringCreateArrayBySeparatingStrings(NULL
, nPath
, CFSTR("/"));
964 _SCNetworkInterfaceCompare(const void *val1
, const void *val2
, void *context
)
966 SCNetworkInterfacePrivateRef dev1
= (SCNetworkInterfacePrivateRef
)val1
;
967 SCNetworkInterfacePrivateRef dev2
= (SCNetworkInterfacePrivateRef
)val2
;
968 CFComparisonResult res
= kCFCompareEqualTo
;
970 /* sort by interface type */
971 if (dev1
->sort_order
!= dev2
->sort_order
) {
972 if (dev1
->sort_order
< dev2
->sort_order
) {
973 res
= kCFCompareLessThan
;
975 res
= kCFCompareGreaterThan
;
980 /* built-in interfaces sort first */
981 if (dev1
->builtin
!= dev2
->builtin
) {
983 res
= kCFCompareLessThan
;
985 res
= kCFCompareGreaterThan
;
990 /* ... and then, sort built-in interfaces by "location" */
992 if (dev1
->location
!= dev2
->location
) {
993 if (isA_CFString(dev1
->location
)) {
994 if (isA_CFString(dev2
->location
)) {
995 res
= CFStringCompare(dev1
->location
, dev2
->location
, 0);
997 res
= kCFCompareLessThan
;
1000 res
= kCFCompareGreaterThan
;
1003 if (res
!= kCFCompareEqualTo
) {
1009 /* ... and, then sort by IOPathMatch */
1010 if ((dev1
->path
!= NULL
) && (dev2
->path
!= NULL
)) {
1011 CFArrayRef elements1
;
1012 CFArrayRef elements2
;
1018 elements1
= split_path(dev1
->path
);
1019 n1
= CFArrayGetCount(elements1
);
1021 elements2
= split_path(dev2
->path
);
1022 n2
= CFArrayGetCount(elements2
);
1024 n
= (n1
<= n2
) ? n1
: n2
;
1025 for (i
= 0; i
< n
; i
++) {
1034 e1
= CFArrayGetValueAtIndex(elements1
, i
);
1035 e2
= CFArrayGetValueAtIndex(elements2
, i
);
1037 str
= _SC_cfstring_to_cstring(e1
, NULL
, 0, kCFStringEncodingUTF8
);
1039 q1
= strtoq(str
, &end
, 16);
1040 isNum
= ((*str
!= '\0') && (*end
== '\0') && (errno
== 0));
1041 CFAllocatorDeallocate(NULL
, str
);
1044 // if e1 is a valid numeric string
1045 str
= _SC_cfstring_to_cstring(e2
, NULL
, 0, kCFStringEncodingUTF8
);
1047 q2
= strtoq(str
, &end
, 16);
1048 isNum
= ((*str
!= '\0') && (*end
== '\0') && (errno
== 0));
1049 CFAllocatorDeallocate(NULL
, str
);
1052 // if e2 is also a valid numeric string
1055 res
= kCFCompareEqualTo
;
1057 } else if (q1
< q2
) {
1058 res
= kCFCompareLessThan
;
1060 res
= kCFCompareGreaterThan
;
1066 res
= CFStringCompare(e1
, e2
, 0);
1067 if (res
!= kCFCompareEqualTo
) {
1072 if (res
== kCFCompareEqualTo
) {
1074 res
= kCFCompareLessThan
;
1075 } else if (n1
< n2
) {
1076 res
= kCFCompareGreaterThan
;
1080 CFRelease(elements1
);
1081 CFRelease(elements2
);
1083 if (res
!= kCFCompareEqualTo
) {
1088 /* ... and, then sort by BSD interface name */
1089 if ((dev1
->entity_device
!= NULL
) && (dev2
->entity_device
!= NULL
)) {
1090 res
= CFStringCompare(dev1
->entity_device
, dev2
->entity_device
, 0);
1091 if (res
!= kCFCompareEqualTo
) {
1096 /* ... and lastly, sort by BSD interface unique identifier */
1097 if ((dev1
->entity_device_unique
!= NULL
) && (dev2
->entity_device_unique
!= NULL
)) {
1098 res
= CFStringCompare(dev1
->entity_device_unique
, dev2
->entity_device_unique
, 0);
1099 // if (res != kCFCompareEqualTo) {
1109 sort_interfaces(CFMutableArrayRef all_interfaces
)
1111 int n
= CFArrayGetCount(all_interfaces
);
1117 CFArraySortValues(all_interfaces
, CFRangeMake(0, n
), _SCNetworkInterfaceCompare
, NULL
);
1124 __SCNetworkInterfaceOrder(SCNetworkInterfaceRef interface
)
1126 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
1128 return interfacePrivate
->sort_order
;
1133 #pragma mark Interface details
1137 IOCopyCFStringValue(CFTypeRef ioVal
)
1139 if (isA_CFString(ioVal
)) {
1140 return CFStringCreateCopy(NULL
, ioVal
);
1143 if (isA_CFData(ioVal
)) {
1144 return CFStringCreateWithCString(NULL
,
1145 (const char *)CFDataGetBytePtr(ioVal
),
1146 kCFStringEncodingUTF8
);
1154 IODictionaryCopyCFStringValue(CFDictionaryRef io_dict
, CFStringRef io_key
)
1158 ioVal
= CFDictionaryGetValue(io_dict
, io_key
);
1159 return IOCopyCFStringValue(ioVal
);
1164 IOStringValueHasPrefix(CFTypeRef ioVal
, CFStringRef prefix
)
1166 Boolean match
= FALSE
;
1167 CFIndex prefixLen
= CFStringGetLength(prefix
);
1168 CFStringRef str
= NULL
;
1170 if (!isA_CFString(ioVal
)) {
1171 if (isA_CFData(ioVal
)) {
1172 str
= CFStringCreateWithCStringNoCopy(NULL
,
1173 (const char *)CFDataGetBytePtr(ioVal
),
1174 kCFStringEncodingUTF8
,
1182 if ((ioVal
!= NULL
) &&
1183 (CFStringGetLength(ioVal
) >= prefixLen
) &&
1184 (CFStringCompareWithOptions(ioVal
,
1186 CFRangeMake(0, prefixLen
),
1187 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
)) {
1191 if (str
!= NULL
) CFRelease(str
);
1196 static const struct {
1197 const CFStringRef name
;
1198 const CFStringRef slot
;
1199 } slot_mappings
[] = {
1201 { CFSTR("A1") , CFSTR("1") },
1202 { CFSTR("B1") , CFSTR("2") },
1203 { CFSTR("C1") , CFSTR("3") },
1205 // Blue&White G3, Yikes G4
1206 { CFSTR("J12"), CFSTR("1") },
1207 { CFSTR("J11"), CFSTR("2") },
1208 { CFSTR("J10"), CFSTR("3") },
1209 { CFSTR("J9"), CFSTR("4") },
1212 { CFSTR("A") , CFSTR("1") },
1213 { CFSTR("B") , CFSTR("2") },
1214 { CFSTR("C") , CFSTR("3") },
1215 { CFSTR("D") , CFSTR("4") },
1217 // Digital Audio G4 (and later models)
1218 { CFSTR("1") , CFSTR("1") },
1219 { CFSTR("2") , CFSTR("2") },
1220 { CFSTR("3") , CFSTR("3") },
1221 { CFSTR("4") , CFSTR("4") },
1222 { CFSTR("5") , CFSTR("5") }
1227 pci_slot(io_registry_entry_t interface
, CFTypeRef
*pci_slot_name
)
1230 io_registry_entry_t parent
;
1231 CFMutableStringRef slot
;
1232 CFTypeRef slot_name
;
1235 if (pci_slot_name
!= NULL
) *pci_slot_name
= NULL
;
1237 slot_name
= IORegistryEntryCreateCFProperty(interface
, CFSTR("AAPL,slot-name"), NULL
, 0);
1238 if (slot_name
!= NULL
) {
1241 slot
= CFStringCreateMutable(NULL
, 0);
1242 if (isA_CFString(slot_name
)) {
1243 if (pci_slot_name
!= NULL
) *pci_slot_name
= CFStringCreateCopy(NULL
, slot_name
);
1244 CFStringAppend(slot
, slot_name
);
1245 } else if (isA_CFData(slot_name
)) {
1246 if (pci_slot_name
!= NULL
) *pci_slot_name
= CFDataCreateCopy(NULL
, slot_name
);
1247 CFStringAppendCString(slot
,
1248 (const char *)CFDataGetBytePtr(slot_name
),
1249 kCFStringEncodingUTF8
);
1252 if (CFStringGetLength(slot
) > 5) {
1253 (void) CFStringFindAndReplace(slot
,
1257 kCFCompareCaseInsensitive
|kCFCompareAnchored
);
1260 for (i
= 0; i
< sizeof(slot_mappings
)/sizeof(slot_mappings
[0]); i
++) {
1261 if (CFStringCompare(slot
,
1262 slot_mappings
[i
].name
,
1263 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
1265 slot
= (CFMutableStringRef
)CFRetain(slot_mappings
[i
].slot
);
1270 CFRelease(slot_name
);
1273 kr
= IORegistryEntryGetParentEntry(interface
, kIOServicePlane
, &parent
);
1275 case kIOReturnSuccess
: {
1276 CFTypeRef parent_pci_slot_name
= NULL
;
1277 CFStringRef parent_slot
;
1279 parent_slot
= pci_slot(parent
, &parent_pci_slot_name
);
1280 if (parent_slot
!= NULL
) {
1281 if (slot
!= NULL
) CFRelease(slot
);
1282 slot
= (CFMutableStringRef
)parent_slot
;
1284 if (pci_slot_name
!= NULL
) {
1285 if (*pci_slot_name
!= NULL
) CFRelease(*pci_slot_name
);
1286 *pci_slot_name
= parent_pci_slot_name
;
1288 CFRelease(parent_pci_slot_name
);
1292 IOObjectRelease(parent
);
1295 case kIOReturnNoDevice
:
1296 // if we have hit the root node
1299 SCLog(TRUE
, LOG_DEBUG
, CFSTR("pci_slot IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr
);
1307 static CFComparisonResult
1308 compare_bsdNames(const void *val1
, const void *val2
, void *context
)
1310 CFStringRef bsd1
= (CFStringRef
)val1
;
1311 CFStringRef bsd2
= (CFStringRef
)val2
;
1313 return CFStringCompare(bsd1
, bsd2
, 0);
1318 pci_port(CFTypeRef slot_name
, CFStringRef bsdName
)
1321 CFStringRef port_name
= NULL
;
1322 CFMutableArrayRef port_names
;
1325 CFStringRef match_keys
[2];
1326 CFTypeRef match_vals
[2];
1327 CFDictionaryRef match_dict
;
1328 CFDictionaryRef matching
;
1329 io_registry_entry_t slot
;
1330 io_iterator_t slot_iterator
= MACH_PORT_NULL
;
1332 match_keys
[0] = CFSTR("AAPL,slot-name");
1333 match_vals
[0] = slot_name
;
1335 match_dict
= CFDictionaryCreate(NULL
,
1336 (const void **)match_keys
,
1337 (const void **)match_vals
,
1339 &kCFTypeDictionaryKeyCallBacks
,
1340 &kCFTypeDictionaryValueCallBacks
);
1342 match_keys
[0] = CFSTR(kIOProviderClassKey
);
1343 match_vals
[0] = CFSTR("IOPCIDevice");
1345 match_keys
[1] = CFSTR(kIOPropertyMatchKey
);
1346 match_vals
[1] = match_dict
;
1348 // note: the "matching" dictionary will be consumed by the following
1349 matching
= CFDictionaryCreate(NULL
,
1350 (const void **)match_keys
,
1351 (const void **)match_vals
,
1352 sizeof(match_keys
)/sizeof(match_keys
[0]),
1353 &kCFTypeDictionaryKeyCallBacks
,
1354 &kCFTypeDictionaryValueCallBacks
);
1355 CFRelease(match_dict
);
1357 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &slot_iterator
);
1358 if (kr
!= kIOReturnSuccess
) {
1359 SCLog(TRUE
, LOG_DEBUG
, CFSTR("pci_port IOServiceGetMatchingServices() failed, kr = 0x%x"), kr
);
1360 return MACH_PORT_NULL
;
1363 port_names
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1365 while ((slot
= IOIteratorNext(slot_iterator
)) != MACH_PORT_NULL
) {
1366 io_registry_entry_t child
;
1367 io_iterator_t child_iterator
= MACH_PORT_NULL
;
1369 kr
= IORegistryEntryCreateIterator(slot
,
1371 kIORegistryIterateRecursively
,
1373 if (kr
!= kIOReturnSuccess
) {
1374 SCLog(TRUE
, LOG_DEBUG
, CFSTR("pci_port IORegistryEntryCreateIterator() failed, kr = 0x%x"), kr
);
1375 CFRelease(port_names
);
1376 return MACH_PORT_NULL
;
1379 while ((child
= IOIteratorNext(child_iterator
)) != MACH_PORT_NULL
) {
1380 if (IOObjectConformsTo(child
, kIONetworkInterfaceClass
)) {
1381 CFStringRef if_bsdName
;
1383 if_bsdName
= IORegistryEntryCreateCFProperty(child
,
1384 CFSTR(kIOBSDNameKey
),
1387 if (if_bsdName
!= NULL
) {
1388 CFArrayAppendValue(port_names
, if_bsdName
);
1389 CFRelease(if_bsdName
);
1392 IOObjectRelease(child
);
1394 IOObjectRelease(child_iterator
);
1395 IOObjectRelease(slot
);
1397 IOObjectRelease(slot_iterator
);
1399 n
= CFArrayGetCount(port_names
);
1401 CFArraySortValues(port_names
, CFRangeMake(0, n
), compare_bsdNames
, NULL
);
1402 n
= CFArrayGetFirstIndexOfValue(port_names
, CFRangeMake(0, n
), bsdName
);
1403 if (n
!= kCFNotFound
) {
1404 port_name
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%d"), n
+ 1);
1408 CFRelease(port_names
);
1414 pci_slot_info(io_registry_entry_t interface
, CFStringRef
*slot_name
, CFStringRef
*port_name
)
1416 CFStringRef bsd_name
;
1418 CFTypeRef pci_slot_name
;
1423 bsd_name
= IORegistryEntryCreateCFProperty(interface
, CFSTR(kIOBSDNameKey
), NULL
, 0);
1424 if (bsd_name
== NULL
) {
1428 *slot_name
= pci_slot(interface
, &pci_slot_name
);
1429 if (*slot_name
!= NULL
) {
1430 if (pci_slot_name
!= NULL
) {
1431 *port_name
= pci_port(pci_slot_name
, bsd_name
);
1432 CFRelease(pci_slot_name
);
1437 CFRelease(bsd_name
);
1443 isBuiltin(io_registry_entry_t interface
)
1447 slot
= pci_slot(interface
, NULL
);
1449 // interfaces which have a "slot" are not built-in
1459 isBluetoothBuiltin(Boolean
*haveController
)
1461 Boolean builtin
= FALSE
;
1462 io_object_t hciController
;
1463 io_iterator_t iter
= MACH_PORT_NULL
;
1466 kr
= IOServiceGetMatchingServices(masterPort
,
1467 IOServiceMatching("IOBluetoothHCIController"),
1469 if ((kr
!= kIOReturnSuccess
) || (iter
== MACH_PORT_NULL
)) {
1470 if (kr
!= kIOReturnSuccess
) {
1471 SCLog(TRUE
, LOG_DEBUG
, CFSTR("isBluetoothBuiltin IOServiceGetMatchingServices() failed, kr = 0x%x"), kr
);
1473 *haveController
= FALSE
;
1476 *haveController
= TRUE
;
1478 hciController
= IOIteratorNext(iter
);
1479 IOObjectRelease(iter
);
1480 if(hciController
!= MACH_PORT_NULL
) {
1481 CFNumberRef idVendor
;
1483 idVendor
= IORegistryEntryCreateCFProperty(hciController
, CFSTR(kUSBVendorID
), NULL
, 0);
1484 if (idVendor
!= NULL
) {
1487 if (isA_CFNumber(idVendor
) &&
1488 CFNumberGetValue(idVendor
, kCFNumberIntType
, &idVendorVal
) &&
1489 (idVendorVal
== kIOUSBVendorIDAppleComputer
)) {
1493 CFRelease(idVendor
);
1496 IOObjectRelease(hciController
);
1504 processUSBInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1505 io_registry_entry_t interface
,
1506 CFDictionaryRef interface_dict
,
1507 io_registry_entry_t controller
,
1508 CFDictionaryRef controller_dict
,
1509 io_registry_entry_t bus
,
1510 CFDictionaryRef bus_dict
)
1513 interfacePrivate
->usb
.name
= IORegistryEntrySearchCFProperty(interface
,
1515 CFSTR(kUSBProductString
),
1517 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1518 interfacePrivate
->usb
.vid
= IORegistryEntrySearchCFProperty(interface
,
1520 CFSTR(kUSBVendorID
),
1522 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1523 interfacePrivate
->usb
.pid
= IORegistryEntrySearchCFProperty(interface
,
1525 CFSTR(kUSBProductID
),
1527 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1534 #pragma mark Interface enumeration
1537 typedef Boolean (*processInterface
)(SCNetworkInterfacePrivateRef interfacePrivate
,
1538 io_registry_entry_t interface
,
1539 CFDictionaryRef interface_dict
,
1540 io_registry_entry_t controller
,
1541 CFDictionaryRef controller_dict
,
1542 io_registry_entry_t bus
,
1543 CFDictionaryRef bus_dict
);
1547 merge_override(SCNetworkInterfacePrivateRef interfacePrivate
,
1548 io_registry_entry_t interface
,
1549 CFStringRef override
)
1554 key
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("Device%@Overrides"), override
);
1555 val
= IORegistryEntrySearchCFProperty(interface
,
1559 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1562 if (isA_CFDictionary(val
)) {
1563 if (interfacePrivate
->overrides
== NULL
) {
1564 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
1566 &kCFTypeDictionaryKeyCallBacks
,
1567 &kCFTypeDictionaryValueCallBacks
);
1569 CFDictionarySetValue(interfacePrivate
->overrides
, override
, val
);
1579 processNetworkInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1580 io_registry_entry_t interface
,
1581 CFDictionaryRef interface_dict
,
1582 io_registry_entry_t controller
,
1583 CFDictionaryRef controller_dict
,
1584 io_registry_entry_t bus
,
1585 CFDictionaryRef bus_dict
)
1595 num
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceType
));
1596 if (isA_CFNumber(num
) &&
1597 CFNumberGetValue(num
, kCFNumberIntType
, &ift
)) {
1598 interfacePrivate
->type
= CFRetain(num
);
1600 SCLog(TRUE
, LOG_DEBUG
, CFSTR("processNetworkInterface() failed, no interface type"));
1608 if ((IOObjectConformsTo(controller
, "IO80211Controller")) ||
1609 (IOObjectConformsTo(controller
, "AirPortPCI" )) ||
1610 (IOObjectConformsTo(controller
, "AirPortDriver" ))) {
1611 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
1612 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1613 interfacePrivate
->sort_order
= kSortAirPort
;
1614 } else if (IOObjectConformsTo(controller
, "IOBluetoothBNEPDriver")) {
1615 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1616 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1617 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
1618 } else if (IOObjectConformsTo(controller
, "AppleUSBEthernetHost")) {
1619 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1620 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1621 interfacePrivate
->sort_order
= kSortTethered
;
1622 } else if (IOObjectConformsTo(controller
, "AppleUSBCDCECMData")) {
1623 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1624 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1625 interfacePrivate
->sort_order
= kSortWWANEthernet
;
1628 if (interfacePrivate
->interface_type
== NULL
) {
1629 val
= IORegistryEntrySearchCFProperty(interface
,
1631 CFSTR(kIOUserEthernetInterfaceRoleKey
),
1633 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1635 if (isA_CFString(val
)) {
1636 if (CFEqual(val
, CFSTR("Bluetooth PAN"))) {
1637 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1638 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1639 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
1640 } else if (CFEqual(val
, CFSTR("Bluetooth PAN-NAP"))) {
1641 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1642 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1643 interfacePrivate
->sort_order
= kSortBluetoothPAN_NAP
;
1644 } else if (CFEqual(val
, CFSTR("Bluetooth P2P"))) {
1645 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1646 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1647 interfacePrivate
->sort_order
= kSortBluetoothPAN_U
;
1655 if (interfacePrivate
->interface_type
== NULL
) {
1656 str
= IODictionaryCopyCFStringValue(bus_dict
, CFSTR("name"));
1658 if (CFEqual(str
, CFSTR("radio"))) {
1659 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
; // ??
1660 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1661 interfacePrivate
->sort_order
= kSortOtherWireless
;
1668 if (interfacePrivate
->interface_type
== NULL
) {
1669 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1670 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1671 interfacePrivate
->sort_order
= kSortEthernet
;
1673 // BOND support only enabled for ethernet devices
1674 interfacePrivate
->supportsBond
= TRUE
;
1677 // enable Bridge support
1678 interfacePrivate
->supportsBridge
= TRUE
;
1681 val
= isA_CFBoolean(CFDictionaryGetValue(interface_dict
, CFSTR(kIOBuiltin
)));
1683 val
= isA_CFBoolean(CFDictionaryGetValue(interface_dict
, CFSTR(kIOPrimaryInterface
)));
1686 interfacePrivate
->builtin
= CFBooleanGetValue(val
);
1688 interfacePrivate
->builtin
= isBuiltin(interface
);
1691 if (!interfacePrivate
->builtin
&&
1692 CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
)) {
1693 // always treat AirPort interfaces as built-in
1694 interfacePrivate
->builtin
= TRUE
;
1698 interfacePrivate
->location
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOLocation
));
1701 num
= CFDictionaryGetValue(controller_dict
, CFSTR(kIOFeatures
));
1702 if (isA_CFNumber(num
) &&
1703 CFNumberGetValue(num
, kCFNumberIntType
, & iVal
)) {
1704 if (iVal
& (kIONetworkFeatureHardwareVlan
| kIONetworkFeatureSoftwareVlan
)) {
1705 interfacePrivate
->supportsVLAN
= TRUE
;
1710 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
)) {
1711 interfacePrivate
->localized_key
= CFSTR("airport");
1712 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_GN
) {
1713 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-gn");
1714 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_NAP
) {
1715 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-nap");
1716 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_U
) {
1717 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-u");
1718 } else if (interfacePrivate
->sort_order
== kSortOtherWireless
) {
1719 interfacePrivate
->localized_key
= CFSTR("wireless");
1720 interfacePrivate
->localized_arg1
= CFRetain(CFSTR("")); // ??
1721 } else if (interfacePrivate
->builtin
) {
1722 if ((interfacePrivate
->location
== NULL
) ||
1723 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1724 interfacePrivate
->localized_key
= CFSTR("ether");
1726 interfacePrivate
->localized_key
= CFSTR("multiether");
1727 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->location
);
1730 CFStringRef provider
;
1732 // check provider class
1733 provider
= IORegistryEntrySearchCFProperty(interface
,
1735 CFSTR(kIOProviderClassKey
),
1737 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1738 if (provider
!= NULL
) {
1739 if (CFEqual(provider
, CFSTR("IOPCIDevice"))) {
1740 CFStringRef port_name
;
1741 CFStringRef slot_name
;
1743 if (pci_slot_info(interface
, &slot_name
, &port_name
)) {
1744 if (port_name
== NULL
) {
1745 interfacePrivate
->localized_key
= CFSTR("pci-ether");
1746 interfacePrivate
->localized_arg1
= slot_name
;
1748 interfacePrivate
->localized_key
= CFSTR("pci-multiether");
1749 interfacePrivate
->localized_arg1
= slot_name
;
1750 interfacePrivate
->localized_arg2
= port_name
;
1753 } else if (CFEqual(provider
, CFSTR("IOUSBDevice")) ||
1754 CFEqual(provider
, CFSTR("IOUSBInterface"))) {
1756 processUSBInterface(interfacePrivate
,
1764 // check if a "Product Name" has been provided
1765 val
= IORegistryEntrySearchCFProperty(interface
,
1767 CFSTR(kIOPropertyProductNameKey
),
1769 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1770 if ((val
== NULL
) && (interfacePrivate
->usb
.name
!= NULL
)) {
1771 // else, use "USB Product Name" if available
1772 val
= CFRetain(interfacePrivate
->usb
.name
);
1775 CFStringRef productName
;
1777 productName
= IOCopyCFStringValue(val
);
1780 if (productName
!= NULL
) {
1781 if (CFStringGetLength(productName
) > 0) {
1782 // if we have a [somewhat reasonable?] product name
1783 if (interfacePrivate
->name
!= NULL
) {
1784 CFRelease(interfacePrivate
->name
);
1786 interfacePrivate
->name
= CFRetain(productName
);
1787 if (interfacePrivate
->localized_name
!= NULL
) {
1788 CFRelease(interfacePrivate
->localized_name
);
1790 interfacePrivate
->localized_name
= copy_interface_string(bundle
, productName
, TRUE
);
1793 CFRelease(productName
);
1796 interfacePrivate
->localized_key
= CFSTR("usb-ether");
1797 interfacePrivate
->localized_arg1
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOBSDNameKey
));
1800 CFRelease(provider
);
1803 if (interfacePrivate
->localized_key
== NULL
) {
1804 // if no provider, not a PCI device, or no slot information
1805 interfacePrivate
->localized_key
= CFSTR("generic-ether");
1806 interfacePrivate
->localized_arg1
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOBSDNameKey
));
1813 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeFireWire
;
1816 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeFireWire
;
1819 interfacePrivate
->builtin
= isBuiltin(interface
);
1822 interfacePrivate
->sort_order
= kSortFireWire
;
1825 if (interfacePrivate
->builtin
) {
1826 interfacePrivate
->localized_key
= CFSTR("firewire");
1828 CFStringRef slot_name
;
1830 slot_name
= pci_slot(interface
, NULL
);
1831 if (slot_name
!= NULL
) {
1832 interfacePrivate
->localized_key
= CFSTR("pci-firewire");
1833 interfacePrivate
->localized_arg1
= slot_name
;
1839 SCLog(TRUE
, LOG_DEBUG
, CFSTR("processNetworkInterface() failed, unknown interface type = %d"), ift
);
1844 interfacePrivate
->entity_device
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOBSDNameKey
));
1846 // Hardware (MAC) address
1847 data
= CFDictionaryGetValue(controller_dict
, CFSTR(kIOMACAddress
));
1848 if (isA_CFData(data
)) {
1849 interfacePrivate
->address
= CFRetain(data
);
1853 num
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceUnit
));
1854 if (isA_CFNumber(num
) &&
1855 CFNumberGetValue(num
, kCFNumberIntType
, & iVal
)) {
1856 interfacePrivate
->unit
= CFRetain(num
);
1859 // configuration [PPP] template override (now deprecated, use NetworkConfigurationOverrides)
1860 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypePPP
);
1867 set_connection_script(SCNetworkInterfacePrivateRef interfacePrivate
, CFStringRef script
)
1869 CFDictionaryRef dict
;
1870 CFMutableDictionaryRef newDict
;
1872 if (interfacePrivate
->overrides
== NULL
) {
1873 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
1875 &kCFTypeDictionaryKeyCallBacks
,
1876 &kCFTypeDictionaryValueCallBacks
);
1879 dict
= CFDictionaryGetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
1881 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
1883 newDict
= CFDictionaryCreateMutable(NULL
,
1885 &kCFTypeDictionaryKeyCallBacks
,
1886 &kCFTypeDictionaryValueCallBacks
);
1888 if (script
!= NULL
) {
1889 CFDictionarySetValue(newDict
, kSCPropNetModemConnectionScript
, script
);
1891 CFDictionaryRemoveValue(newDict
, kSCPropNetModemConnectionScript
);
1893 if (CFDictionaryGetCount(newDict
) > 0) {
1894 CFDictionarySetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
, newDict
);
1896 CFDictionaryRemoveValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
1900 if (CFDictionaryGetCount(interfacePrivate
->overrides
) == 0) {
1901 CFRelease(interfacePrivate
->overrides
);
1902 interfacePrivate
->overrides
= NULL
;
1909 is_valid_connection_script(CFStringRef script
)
1911 char ccl
[MAXPATHLEN
];
1912 char path
[MAXPATHLEN
];
1913 NSSearchPathEnumerationState state
;
1915 (void) _SC_cfstring_to_cstring(script
,
1918 kCFStringEncodingUTF8
);
1920 state
= NSStartSearchPathEnumeration(NSLibraryDirectory
,
1921 NSLocalDomainMask
|NSSystemDomainMask
);
1922 while ((state
= NSGetNextSearchPathEnumeration(state
, path
))) {
1924 struct stat statBuf
;
1926 if (ccl
[0] == '/') {
1927 path
[0] = '\0'; // if modemCCL is a full path
1929 strlcat(path
, "/Modem Scripts/", sizeof(path
));
1931 strlcat(path
, ccl
, sizeof(path
));
1933 if (stat(path
, &statBuf
) != 0) {
1934 if (errno
== ENOENT
) {
1938 SCLog(TRUE
, LOG_DEBUG
,
1939 CFSTR("processSerialInterface stat() failed: %s"),
1943 if (S_ISREG(statBuf
.st_mode
)) {
1944 // if we have a valid CCL script
1948 #define BUNDLE_EXT ".ccl"
1949 #define BUNDLE_EXT_LEN sizeof(BUNDLE_EXT) - 1
1954 if ((n
<= BUNDLE_EXT_LEN
) ||
1955 (strstr(&path
[n
- BUNDLE_EXT_LEN
], BUNDLE_EXT
) == NULL
)) {
1956 strlcat(path
, BUNDLE_EXT
, sizeof(path
));
1957 if (stat(path
, &statBuf
) != 0) {
1958 if (errno
== ENOENT
) {
1962 SCLog(TRUE
, LOG_DEBUG
,
1963 CFSTR("processSerialInterface stat() failed: %s"),
1968 if (S_ISDIR(statBuf
.st_mode
)) {
1969 // if we have a valid CCL bundle
1979 processSerialInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1980 io_registry_entry_t interface
,
1981 CFDictionaryRef interface_dict
,
1982 io_registry_entry_t controller
,
1983 CFDictionaryRef controller_dict
,
1984 io_registry_entry_t bus
,
1985 CFDictionaryRef bus_dict
)
1987 CFStringRef base
= NULL
;
1989 Boolean isModem
= FALSE
;
1990 Boolean isWWAN
= FALSE
;
1991 CFStringRef modemCCL
= NULL
;
1996 val
= IORegistryEntrySearchCFProperty(interface
,
1998 kSCNetworkInterfaceHiddenPortKey
,
2000 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2003 return FALSE
; // if this interface should not be exposed
2006 // check if initializing
2007 val
= IORegistryEntrySearchCFProperty(interface
,
2009 kSCNetworkInterfaceInitializingKey
,
2011 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2013 Boolean initializing
;
2015 initializing
= isA_CFBoolean(val
) && CFBooleanGetValue(val
);
2018 return FALSE
; // if this interface is still initializing
2023 val
= IORegistryEntrySearchCFProperty(interface
,
2027 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2029 isWWAN
= isA_CFBoolean(val
) && CFBooleanGetValue(val
);
2034 interfacePrivate
->entity_device
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOTTYDeviceKey
));
2035 if (interfacePrivate
->entity_device
== NULL
) {
2039 base
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOTTYBaseNameKey
));
2041 base
= CFRetain(interfacePrivate
->entity_device
);
2047 * Exclude ports named "irda" because otherwise the IrDA ports on the
2048 * original iMac (rev's A through D) show up as serial ports. Given
2049 * that only the rev A actually had an IrDA port, and Mac OS X doesn't
2050 * even support it, these ports definitely shouldn't be listed.
2052 if (CFStringCompare(base
,
2054 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
2058 if (IOStringValueHasPrefix(base
, CFSTR("bluetooth"))) {
2059 Boolean haveController
= FALSE
;
2062 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBluetooth
;
2063 interfacePrivate
->sort_order
= kSortBluetooth
;
2064 interfacePrivate
->builtin
= isBluetoothBuiltin(&haveController
);
2065 if (!haveController
) {
2066 // if device with no controller present
2069 } else if (IOStringValueHasPrefix(base
, CFSTR("irda-ircomm"))) {
2071 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIrDA
;
2072 interfacePrivate
->sort_order
= kSortIrDA
;
2073 } else if (isWWAN
) {
2075 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeWWAN
;
2076 interfacePrivate
->sort_order
= kSortWWAN
;
2079 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeModem
;
2080 interfacePrivate
->sort_order
= kSortModem
;
2083 val
= IORegistryEntrySearchCFProperty(interface
,
2085 CFSTR(kIODeviceSupportsHoldKey
),
2087 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2091 if (isA_CFNumber(val
) &&
2092 CFNumberGetValue(val
, kCFNumberSInt32Type
, &v92
)) {
2093 interfacePrivate
->modemIsV92
= (v92
== 1);
2100 interfacePrivate
->entity_type
= kSCEntNetModem
;
2102 // Entity (Hardware)
2103 ift
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOSerialBSDTypeKey
));
2104 if (!isA_CFString(ift
)) {
2108 if (CFEqual(ift
, CFSTR(kIOSerialBSDModemType
))) {
2112 if (CFEqual(base
, CFSTR("modem"))) {
2113 interfacePrivate
->builtin
= TRUE
;
2114 interfacePrivate
->sort_order
= kSortInternalModem
;
2115 } else if (CFEqual(base
, CFSTR("usbmodem"))) {
2116 interfacePrivate
->sort_order
= kSortUSBModem
;
2118 } else if (CFEqual(ift
, CFSTR(kIOSerialBSDRS232Type
))) {
2120 interfacePrivate
->sort_order
= kSortSerialPort
;
2125 // configuration [PPP] template override (now deprecated, use NetworkConfigurationOverrides)
2126 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypePPP
);
2128 // configuration [Modem] template override (now deprecated, use NetworkConfigurationOverrides)
2129 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypeModem
);
2131 // look for modem CCL, unique identifier
2132 if (interfacePrivate
->overrides
!= NULL
) {
2133 val
= CFDictionaryGetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
2135 CFStringRef uniqueID
;
2137 modemCCL
= CFDictionaryGetValue(val
, kSCPropNetModemConnectionScript
);
2138 modemCCL
= isA_CFString(modemCCL
);
2140 uniqueID
= CFDictionaryGetValue(val
, CFSTR("UniqueIdentifier"));
2141 uniqueID
= isA_CFString(uniqueID
);
2142 if (uniqueID
!= NULL
) {
2143 // retain the device's base name and the unique id
2144 CFRelease(interfacePrivate
->entity_device
);
2145 interfacePrivate
->entity_device
= CFRetain(base
);
2146 interfacePrivate
->entity_device_unique
= CFStringCreateCopy(NULL
, uniqueID
);
2151 // if not part of the NetworkConfigurationOverrides/DeviceModemOverrides, look
2152 // a bit harder for the modem CCL
2153 if (modemCCL
== NULL
) {
2154 val
= IORegistryEntrySearchCFProperty(interface
,
2158 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2160 modemCCL
= IOCopyCFStringValue(val
);
2161 if (modemCCL
!= NULL
) {
2162 set_connection_script(interfacePrivate
, modemCCL
);
2163 CFRelease(modemCCL
);
2171 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIrDA
)) {
2172 interfacePrivate
->localized_key
= CFSTR("irda");
2173 } else if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBluetooth
)) {
2174 interfacePrivate
->localized_key
= CFSTR("bluetooth");
2176 CFStringRef localized
= NULL
;
2177 CFStringRef name
= NULL
;
2178 CFMutableStringRef port
;
2180 port
= CFStringCreateMutableCopy(NULL
, 0, base
);
2181 CFStringLowercase(port
, NULL
);
2184 CFStringAppend(port
, CFSTR("-port"));
2187 // set non-localized name
2188 if (bundle
!= NULL
) {
2189 name
= copy_interface_string(bundle
, port
, FALSE
);
2192 if (!CFEqual(port
, name
)) {
2193 // if [English] localization available
2194 interfacePrivate
->name
= name
;
2196 // if no [English] localization available, use TTY base name
2198 interfacePrivate
->name
= CFStringCreateCopy(NULL
, base
);
2201 interfacePrivate
->name
= CFStringCreateCopy(NULL
, base
);
2204 // set localized name
2205 if (bundle
!= NULL
) {
2206 localized
= copy_interface_string(bundle
, port
, TRUE
);
2208 if (localized
!= NULL
) {
2209 if (!CFEqual(port
, localized
)) {
2210 // if localization available
2211 interfacePrivate
->localized_name
= localized
;
2213 // if no localization available, use TTY base name
2214 CFRelease(localized
);
2215 interfacePrivate
->localized_name
= CFStringCreateCopy(NULL
, base
);
2218 interfacePrivate
->localized_name
= CFStringCreateCopy(NULL
, base
);
2221 if (!isModem
|| !CFEqual(base
, CFSTR("modem"))) {
2222 CFStringRef productName
;
2224 // check if a "Product Name" has been provided
2225 val
= IORegistryEntrySearchCFProperty(interface
,
2227 CFSTR(kIOPropertyProductNameKey
),
2229 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2231 // check if a "USB Product Name" has been provided
2232 val
= IORegistryEntrySearchCFProperty(interface
,
2234 CFSTR(kUSBProductString
),
2236 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2239 productName
= IOCopyCFStringValue(val
);
2242 if (productName
!= NULL
) {
2243 if (CFStringGetLength(productName
) > 0) {
2244 // if we have a [somewhat reasonable?] product name
2245 if (interfacePrivate
->name
!= NULL
) {
2246 CFRelease(interfacePrivate
->name
);
2248 interfacePrivate
->name
= CFRetain(productName
);
2249 if (interfacePrivate
->localized_name
!= NULL
) {
2250 CFRelease(interfacePrivate
->localized_name
);
2252 interfacePrivate
->localized_name
= copy_interface_string(bundle
, productName
, TRUE
);
2254 // if not provided, also check if the product name
2255 // matches a CCL script
2256 if ((modemCCL
== NULL
) &&
2257 is_valid_connection_script(productName
)) {
2258 set_connection_script(interfacePrivate
, productName
);
2262 CFRelease(productName
);
2274 if (!ok
&& (interfacePrivate
->entity_device
!= NULL
)) {
2275 CFRelease(interfacePrivate
->entity_device
);
2276 interfacePrivate
->entity_device
= NULL
;
2278 if (base
!= NULL
) CFRelease(base
);
2284 static SCNetworkInterfaceRef
2285 createInterface(io_registry_entry_t interface
, processInterface func
)
2287 io_registry_entry_t bus
= MACH_PORT_NULL
;
2288 CFMutableDictionaryRef bus_dict
= NULL
;
2289 io_registry_entry_t controller
= MACH_PORT_NULL
;
2290 CFMutableDictionaryRef controller_dict
= NULL
;
2291 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
2292 CFMutableDictionaryRef interface_dict
= NULL
;
2297 kr
= IORegistryEntryGetPath(interface
, kIOServicePlane
, path
);
2298 if (kr
!= kIOReturnSuccess
) {
2299 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryGetPath() failed, kr = 0x%x"), kr
);
2303 kr
= IORegistryEntryCreateCFProperties(interface
, &interface_dict
, NULL
, kNilOptions
);
2304 if (kr
!= kIOReturnSuccess
) {
2305 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryCreateCFProperties() failed, kr = 0x%x"), kr
);
2309 /* get the controller node */
2310 kr
= IORegistryEntryGetParentEntry(interface
, kIOServicePlane
, &controller
);
2311 if (kr
!= KERN_SUCCESS
) {
2312 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr
);
2316 /* get the dictionary associated with the node */
2317 kr
= IORegistryEntryCreateCFProperties(controller
, &controller_dict
, NULL
, kNilOptions
);
2318 if (kr
!= KERN_SUCCESS
) {
2319 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryCreateCFProperties() failed, kr = 0x%x"), kr
);
2323 /* get the bus node */
2324 kr
= IORegistryEntryGetParentEntry(controller
, kIOServicePlane
, &bus
);
2325 if (kr
!= KERN_SUCCESS
) {
2326 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr
);
2330 /* get the dictionary associated with the node */
2331 kr
= IORegistryEntryCreateCFProperties(bus
, &bus_dict
, NULL
, kNilOptions
);
2332 if (kr
!= KERN_SUCCESS
) {
2333 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryCreateCFProperties() failed, kr = 0x%x"), kr
);
2337 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
, path
);
2339 // configuration [PPP, Modem, DNS, IPv4, IPv6, Proxies, SMB] template overrides
2340 val
= IORegistryEntrySearchCFProperty(interface
,
2342 kSCNetworkInterfaceNetworkConfigurationOverridesKey
,
2344 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2346 if (isA_CFDictionary(val
)) {
2347 interfacePrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, val
);
2352 if ((*func
)(interfacePrivate
, interface
, interface_dict
, controller
, controller_dict
, bus
, bus_dict
)) {
2353 /* get user-notification / auto-configuration preference */
2354 val
= IORegistryEntrySearchCFProperty(interface
,
2356 kSCNetworkInterfaceConfigurationActionKey
,
2358 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2360 if (isA_CFString(val
)) {
2361 interfacePrivate
->configurationAction
= CFRetain(val
);
2366 /* get HiddenConfiguration preference */
2367 val
= IORegistryEntrySearchCFProperty(interface
,
2369 kSCNetworkInterfaceHiddenConfigurationKey
,
2371 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2373 interfacePrivate
->hidden
= TRUE
;
2377 CFRelease(interfacePrivate
);
2378 interfacePrivate
= NULL
;
2383 if (interface_dict
!= NULL
) CFRelease(interface_dict
);
2385 if (controller
!= MACH_PORT_NULL
) IOObjectRelease(controller
);
2386 if (controller_dict
!= NULL
) CFRelease(controller_dict
);
2388 if (bus
!= MACH_PORT_NULL
) IOObjectRelease(bus
);
2389 if (bus_dict
!= NULL
) CFRelease(bus_dict
);
2391 return (SCNetworkInterfaceRef
)interfacePrivate
;
2396 findMatchingInterfaces(CFDictionaryRef matching
, processInterface func
)
2398 CFMutableArrayRef interfaces
;
2399 io_registry_entry_t interface
;
2401 io_iterator_t iterator
= MACH_PORT_NULL
;
2404 * A reference to the "matching" dictionary will be consumed by the
2405 * the call to IOServiceGetMatchingServices so we bump up the retain
2410 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &iterator
);
2411 if (kr
!= kIOReturnSuccess
) {
2412 SCLog(TRUE
, LOG_DEBUG
, CFSTR("findMatchingInterfaces IOServiceGetMatchingServices() failed, kr = 0x%x"), kr
);
2416 interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2418 while ((interface
= IOIteratorNext(iterator
)) != MACH_PORT_NULL
) {
2419 SCNetworkInterfaceRef match
;
2421 match
= createInterface(interface
, func
);
2422 if (match
!= NULL
) {
2423 CFArrayAppendValue(interfaces
, match
);
2427 IOObjectRelease(interface
);
2430 IOObjectRelease(iterator
);
2437 #pragma mark helper functions
2441 findConfiguration(CFStringRef interface_type
)
2445 for (i
= 0; i
< sizeof(configurations
)/sizeof(configurations
[0]); i
++) {
2446 if (CFEqual(interface_type
, *configurations
[i
].interface_type
)) {
2457 __SCNetworkInterfaceGetDefaultConfigurationType(SCNetworkInterfaceRef interface
)
2459 CFIndex interfaceIndex
;
2460 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2462 if (interfacePrivate
->serviceID
== NULL
) {
2463 // if not associated with a service (yet)
2464 _SCErrorSet(kSCStatusInvalidArgument
);
2468 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2469 if (interfaceIndex
== kCFNotFound
) {
2470 // unknown interface type, use per-service configuration preferences
2471 return interfacePrivate
->interface_type
; // entity
2474 if (configurations
[interfaceIndex
].entity_hardware
!= NULL
) {
2475 // if configuration information can be associated with this interface type
2476 return *configurations
[interfaceIndex
].entity_hardware
;
2479 _SCErrorSet(kSCStatusInvalidArgument
);
2486 __SCNetworkInterfaceIsValidExtendedConfigurationType(SCNetworkInterfaceRef interface
,
2487 CFStringRef extendedType
,
2488 Boolean requirePerInterface
)
2490 CFStringRef defaultType
;
2491 CFIndex extendedIndex
;
2492 CFIndex interfaceIndex
;
2493 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2494 Boolean isL2TP
= FALSE
;
2497 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
2498 if (defaultType
== NULL
) {
2502 if (CFEqual(extendedType
, defaultType
)) {
2503 // extended and default configuration types cannot conflict
2507 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2508 if (interfaceIndex
== kCFNotFound
) {
2509 // configuration information for unknown interface type's
2510 // are stored along with the service and we don't allow
2511 // per-service extended configurations
2515 if (CFEqual(extendedType
, kSCEntNetIPSec
)) {
2516 CFStringRef interfaceType
;
2518 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
2519 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
2520 SCNetworkInterfaceRef child
;
2522 child
= SCNetworkInterfaceGetInterface(interface
);
2523 if (child
!= NULL
) {
2524 interfaceType
= SCNetworkInterfaceGetInterfaceType(child
);
2525 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
2532 if (requirePerInterface
&&
2533 !configurations
[interfaceIndex
].per_interface_config
&&
2535 // we don't allow per-service extended configurations (except
2536 // that we do allow IPSec as an extended type for PPP->L2TP)
2540 extendedIndex
= findConfiguration(extendedType
);
2541 if ((extendedIndex
!= kCFNotFound
) && !isL2TP
) {
2542 // extended type cannot match a known interface type (except
2543 // that we do allow IPSec as an extended type for PPP->L2TP)
2549 * Do we match specific/known extended configuration types (e.g. EAPOL)
2550 * and ensure that any non-standard extended configuration types be of
2551 * the form com.myCompany.myType?
2560 _SCErrorSet(kSCStatusInvalidArgument
);
2567 CFStringRef defaultType
;
2568 CFMutableArrayRef types
;
2569 } extendedConfiguration
, *extendedConfigurationRef
;
2573 __addExtendedConfigurationType(const void *key
, const void *value
, void *context
)
2575 CFStringRef extendedType
= (CFStringRef
)key
;
2576 extendedConfigurationRef myContextRef
= (extendedConfigurationRef
)context
;
2578 if (CFEqual(extendedType
, myContextRef
->defaultType
)) {
2579 // do not include the default configuration type
2583 if (CFArrayContainsValue(myContextRef
->types
,
2584 CFRangeMake(0, CFArrayGetCount(myContextRef
->types
)),
2586 // if extendedType already has already been added
2590 CFArrayAppendValue(myContextRef
->types
, extendedType
);
2597 extendedConfigurationTypes(SCNetworkInterfaceRef interface
)
2600 CFIndex interfaceIndex
;
2601 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2602 extendedConfiguration myContext
;
2603 SCNetworkServiceRef service
;
2607 myContext
.defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
2608 if (myContext
.defaultType
== NULL
) {
2609 myContext
.types
= NULL
;
2613 myContext
.types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2615 if (interfacePrivate
->serviceID
== NULL
) {
2616 // if not associated with a service (yet)
2620 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2621 if (interfaceIndex
== kCFNotFound
) {
2622 // we don't allow per-service extended configurations
2626 if (!configurations
[interfaceIndex
].per_interface_config
) {
2627 // known interface type but we still don't allow
2628 // per-service extended configurations
2632 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
2633 interfacePrivate
->prefs
,
2634 interfacePrivate
->serviceID
,
2637 sets
= SCNetworkSetCopyAll(interfacePrivate
->prefs
);
2638 n
= (sets
!= NULL
) ? CFArrayGetCount(sets
) : 0;
2640 for (i
= 0; i
< n
; i
++) {
2641 CFDictionaryRef configs
;
2644 CFArrayRef services
;
2645 SCNetworkSetRef set
;
2647 set
= CFArrayGetValueAtIndex(sets
, i
);
2648 services
= SCNetworkSetCopyServices(set
);
2649 found
= CFArrayContainsValue(services
,
2650 CFRangeMake(0, CFArrayGetCount(services
)),
2652 CFRelease(services
);
2658 // add stored extended configuration types
2659 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
2660 SCNetworkSetGetSetID(set
), // set
2661 interfacePrivate
->entity_device
, // service
2663 configs
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
2665 if (isA_CFDictionary(configs
)) {
2666 CFDictionaryApplyFunction(configs
,
2667 __addExtendedConfigurationType
,
2671 // add not-yet-stored extended configuration types
2672 if (interfacePrivate
->unsaved
!= NULL
) {
2673 CFDictionaryApplyFunction(interfacePrivate
->unsaved
,
2674 __addExtendedConfigurationType
,
2682 if (sets
!= NULL
) CFRelease(sets
);
2686 return myContext
.types
;
2691 copyConfigurationPaths(SCNetworkInterfacePrivateRef interfacePrivate
,
2692 CFStringRef extendedType
)
2694 CFMutableArrayRef array
;
2696 CFIndex interfaceIndex
;
2699 SCNetworkServiceRef service
;
2702 array
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2704 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2705 if (interfaceIndex
== kCFNotFound
) {
2706 // unknown interface type, use per-service configuration preferences
2707 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
2708 interfacePrivate
->serviceID
, // service
2709 extendedType
); // entity
2710 CFArrayAppendValue(array
, path
);
2715 if (!configurations
[interfaceIndex
].per_interface_config
) {
2716 // known interface type, per-service configuration preferences
2717 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
2718 interfacePrivate
->serviceID
, // service
2719 extendedType
); // entity
2720 CFArrayAppendValue(array
, path
);
2725 // known interface type, per-interface configuration preferences
2727 // 1. look for all sets which contain the associated service
2728 // 2. add a per-set path for the interface configuration for
2731 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
2732 interfacePrivate
->prefs
,
2733 interfacePrivate
->serviceID
,
2734 (SCNetworkInterfaceRef
)interfacePrivate
);
2736 sets
= SCNetworkSetCopyAll(interfacePrivate
->prefs
);
2737 n
= (sets
!= NULL
) ? CFArrayGetCount(sets
) : 0;
2739 for (i
= 0; i
< n
; i
++) {
2740 CFArrayRef services
;
2741 SCNetworkSetRef set
;
2743 set
= CFArrayGetValueAtIndex(sets
, i
);
2744 services
= SCNetworkSetCopyServices(set
);
2745 if (CFArrayContainsValue(services
,
2746 CFRangeMake(0, CFArrayGetCount(services
)),
2748 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
2749 SCNetworkSetGetSetID(set
), // set
2750 interfacePrivate
->entity_device
, // service
2751 extendedType
); // entity
2752 CFArrayAppendValue(array
, path
);
2755 CFRelease(services
);
2758 if (CFArrayGetCount(array
) == 0) {
2764 if (sets
!= NULL
) CFRelease(sets
);
2770 #pragma mark SCNetworkInterface <--> preferences entity
2775 __SCNetworkInterfaceCopyInterfaceEntity(SCNetworkInterfaceRef interface
)
2777 CFMutableDictionaryRef entity
;
2778 CFIndex interfaceIndex
;
2779 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2781 entity
= CFDictionaryCreateMutable(NULL
,
2783 &kCFTypeDictionaryKeyCallBacks
,
2784 &kCFTypeDictionaryValueCallBacks
);
2785 if (interfacePrivate
->entity_type
!= NULL
) {
2786 CFDictionarySetValue(entity
,
2787 kSCPropNetInterfaceType
,
2788 interfacePrivate
->entity_type
);
2790 if (interfacePrivate
->entity_subtype
!= NULL
) {
2791 CFDictionarySetValue(entity
,
2792 kSCPropNetInterfaceSubType
,
2793 interfacePrivate
->entity_subtype
);
2795 if (interfacePrivate
->entity_device
!= NULL
) {
2796 CFDictionarySetValue(entity
,
2797 kSCPropNetInterfaceDeviceName
,
2798 interfacePrivate
->entity_device
);
2800 if (interfacePrivate
->entity_device_unique
!= NULL
) {
2801 CFDictionarySetValue(entity
,
2802 CFSTR("DeviceUniqueIdentifier"),
2803 interfacePrivate
->entity_device_unique
);
2805 if (interfacePrivate
->hidden
) {
2806 CFDictionarySetValue(entity
,
2807 kSCNetworkInterfaceHiddenConfigurationKey
,
2811 // match the "hardware" with the lowest layer
2813 SCNetworkInterfaceRef nextInterface
;
2815 nextInterface
= SCNetworkInterfaceGetInterface(interface
);
2816 if (nextInterface
== NULL
) {
2820 interface
= nextInterface
;
2822 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2824 if (CFEqual(interface
, kSCNetworkInterfaceIPv4
)) {
2828 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2829 if (interfaceIndex
!= kCFNotFound
) {
2830 if (configurations
[interfaceIndex
].entity_hardware
!= NULL
) {
2831 CFDictionarySetValue(entity
,
2832 kSCPropNetInterfaceHardware
,
2833 *configurations
[interfaceIndex
].entity_hardware
);
2836 CFDictionarySetValue(entity
,
2837 kSCPropNetInterfaceHardware
,
2838 interfacePrivate
->interface_type
);
2841 // add the localized display name (which will only be used when/if the
2842 // interface is removed from the system)
2843 CFDictionarySetValue(entity
,
2844 kSCPropUserDefinedName
,
2845 SCNetworkInterfaceGetLocalizedDisplayName(interface
));
2847 // note that this is a V.92 capable modem
2848 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeModem
) &&
2849 interfacePrivate
->modemIsV92
) {
2853 num
= CFNumberCreate(NULL
, kCFNumberIntType
, &one
);
2854 CFDictionarySetValue(entity
,
2855 kSCPropNetInterfaceSupportsModemOnHold
,
2864 static SCNetworkInterfaceRef
2865 findInterface(CFArrayRef interfaces
, CFStringRef match_if
)
2870 n
= CFArrayGetCount(interfaces
);
2871 for (i
= 0; i
< n
; i
++) {
2872 SCNetworkInterfaceRef interface
= CFArrayGetValueAtIndex(interfaces
, i
);
2873 CFStringRef interfaceName
;
2875 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
2876 if ((interfaceName
!= NULL
) && CFEqual(interfaceName
, match_if
)) {
2877 CFRetain(interface
);
2885 static SCNetworkInterfaceRef
2886 findBondInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
2889 SCNetworkInterfaceRef interface
= NULL
;
2891 if (prefs
== NULL
) {
2895 // check if the interface is an Ethernet Bond
2896 bonds
= SCBondInterfaceCopyAll(prefs
);
2897 if (bonds
!= NULL
) {
2898 interface
= findInterface(bonds
, ifDevice
);
2904 static SCNetworkInterfaceRef
2905 findBridgeInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
2908 SCNetworkInterfaceRef interface
= NULL
;
2910 if (prefs
== NULL
) {
2914 // check if the interface is an bridge
2915 bridges
= SCBridgeInterfaceCopyAll(prefs
);
2916 if (bridges
!= NULL
) {
2917 interface
= findInterface(bridges
, ifDevice
);
2923 static SCNetworkInterfaceRef
2924 findVLANInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
2926 SCNetworkInterfaceRef interface
= NULL
;
2929 if (prefs
== NULL
) {
2933 // check if the interface is a VLAN
2934 vlans
= SCVLANInterfaceCopyAll(prefs
);
2935 if (vlans
!= NULL
) {
2936 interface
= findInterface(vlans
, ifDevice
);
2943 SCNetworkInterfaceRef
2944 _SCNetworkInterfaceCreateWithBSDName(CFAllocatorRef allocator
,
2945 CFStringRef bsdName
,
2948 CFMutableDictionaryRef entity
;
2949 SCNetworkInterfaceRef interface
;
2951 entity
= CFDictionaryCreateMutable(NULL
,
2953 &kCFTypeDictionaryKeyCallBacks
,
2954 &kCFTypeDictionaryValueCallBacks
);
2955 CFDictionarySetValue(entity
, kSCPropNetInterfaceDeviceName
, bsdName
);
2957 if ((flags
& kIncludeBondInterfaces
) == 0) {
2958 CFDictionarySetValue(entity
, CFSTR("_NO_BOND_INTERFACES_"), kCFBooleanTrue
);
2961 if ((flags
& kIncludeBridgeInterfaces
) == 0) {
2962 CFDictionarySetValue(entity
, CFSTR("_NO_BRIDGE_INTERFACES_"), kCFBooleanTrue
);
2965 if ((flags
& kIncludeVLANInterfaces
) == 0) {
2966 CFDictionarySetValue(entity
, CFSTR("_NO_VLAN_INTERFACES_"), kCFBooleanTrue
);
2969 interface
= _SCNetworkInterfaceCreateWithEntity(NULL
, entity
, NULL
);
2977 __SCNetworkInterfaceSetService(SCNetworkInterfaceRef interface
,
2978 SCNetworkServiceRef service
)
2980 SCNetworkInterfacePrivateRef interfacePrivate
;
2981 SCNetworkServicePrivateRef servicePrivate
;
2983 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2984 if (interfacePrivate
->prefs
!= NULL
) {
2985 CFRelease(interfacePrivate
->prefs
);
2986 interfacePrivate
->prefs
= NULL
;
2988 if (interfacePrivate
->serviceID
!= NULL
) {
2989 CFRelease(interfacePrivate
->serviceID
);
2990 interfacePrivate
->serviceID
= NULL
;
2993 servicePrivate
= (SCNetworkServicePrivateRef
)service
;
2994 if (servicePrivate
->prefs
!= NULL
) {
2995 interfacePrivate
->prefs
= CFRetain(servicePrivate
->prefs
);
2997 if (servicePrivate
->serviceID
!= NULL
) {
2998 interfacePrivate
->serviceID
= CFRetain(servicePrivate
->serviceID
);
3006 _SCNetworkInterfaceMatchesName(CFStringRef name
, CFStringRef key
)
3011 if (bundle
== NULL
) {
3016 if (!isA_CFString(name
)) {
3017 // if no interface "name"
3021 // check non-localized name for a match
3022 str
= copy_interface_string(bundle
, key
, FALSE
);
3024 match
= CFEqual(name
, str
);
3031 // check localized name for a match
3032 str
= copy_interface_string(bundle
, key
, TRUE
);
3034 match
= CFEqual(name
, str
);
3045 SCNetworkInterfaceRef
3046 _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef allocator
,
3047 CFDictionaryRef interface_entity
,
3048 SCNetworkServiceRef service
)
3050 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
3051 CFStringRef ifDevice
;
3052 CFStringRef ifName
= NULL
;
3053 CFStringRef ifSubType
;
3055 CFStringRef ifUnique
;
3056 CFArrayRef matching_interfaces
= NULL
;
3058 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
3059 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
3061 ifType
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceType
);
3062 if (ifType
== NULL
) {
3064 * The interface "Type" was not specified. We'll make an
3065 * assumption that this is an "Ethernet" interface. If a
3066 * real interface exists with the provided interface name
3067 * then the actual type will be set accordingly. If not, we'll
3068 * end up crafting an "Ethernet" SCNetworkInterface which
3069 * will keep the rest of the configuration APIs happy.
3071 ifType
= kSCValNetInterfaceTypeEthernet
;
3074 if (!isA_CFString(ifType
)) {
3078 ifSubType
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceSubType
);
3079 if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) ||
3080 CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
3081 if (!isA_CFString(ifSubType
)) {
3086 ifDevice
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceDeviceName
);
3087 ifUnique
= CFDictionaryGetValue(interface_entity
, CFSTR("DeviceUniqueIdentifier"));
3089 if (CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
) ||
3090 CFEqual(ifType
, kSCValNetInterfaceTypeFireWire
) ||
3091 (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) && CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPoE
))) {
3092 char bsdName
[IFNAMSIZ
];
3093 CFMutableDictionaryRef matching
;
3095 if (!isA_CFString(ifDevice
)) {
3099 if (CFEqual(ifDevice
, CFSTR("lo0"))) { // for _SCNetworkInterfaceCreateWithBSDName
3100 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
3104 if (_SC_cfstring_to_cstring(ifDevice
, bsdName
, sizeof(bsdName
), kCFStringEncodingASCII
) == NULL
) {
3108 matching
= IOBSDNameMatching(masterPort
, 0, bsdName
);
3109 if (matching
== NULL
) {
3112 matching_interfaces
= findMatchingInterfaces(matching
, processNetworkInterface
);
3113 CFRelease(matching
);
3114 } else if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
3115 if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPSerial
)) {
3116 CFDictionaryRef matching
;
3117 CFStringRef match_keys
[2];
3118 CFStringRef match_vals
[2];
3120 if (!isA_CFString(ifDevice
)) {
3124 match_keys
[0] = CFSTR(kIOProviderClassKey
);
3125 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
3127 match_keys
[1] = CFSTR(kIOTTYBaseNameKey
);
3128 match_vals
[1] = ifDevice
;
3130 matching
= CFDictionaryCreate(NULL
,
3131 (const void **)match_keys
,
3132 (const void **)match_vals
,
3133 sizeof(match_keys
)/sizeof(match_keys
[0]),
3134 &kCFTypeDictionaryKeyCallBacks
,
3135 &kCFTypeDictionaryValueCallBacks
);
3136 matching_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
);
3137 CFRelease(matching
);
3139 if (ifUnique
== NULL
) {
3141 Boolean useDeviceName
= TRUE
;
3143 n
= (matching_interfaces
!= NULL
) ? CFArrayGetCount(matching_interfaces
) : 0;
3147 for (i
= 0; i
< n
; i
++) {
3148 SCNetworkInterfacePrivateRef scanPrivate
;
3150 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
3151 if (scanPrivate
->entity_device_unique
!= NULL
) {
3152 useDeviceName
= FALSE
;
3158 if (useDeviceName
) {
3159 if (matching_interfaces
!= NULL
) {
3160 CFRelease(matching_interfaces
);
3163 match_keys
[1] = CFSTR(kIOTTYDeviceKey
);
3164 matching
= CFDictionaryCreate(NULL
,
3165 (const void **)match_keys
,
3166 (const void **)match_vals
,
3167 sizeof(match_keys
)/sizeof(match_keys
[0]),
3168 &kCFTypeDictionaryKeyCallBacks
,
3169 &kCFTypeDictionaryValueCallBacks
);
3170 matching_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
);
3171 CFRelease(matching
);
3174 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypeL2TP
)) {
3175 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
3176 kSCNetworkInterfaceTypeL2TP
);
3177 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPTP
)) {
3178 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
3179 kSCNetworkInterfaceTypePPTP
);
3181 // XXX do we allow non-Apple variants of PPP??? XXX
3182 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
3185 } else if (CFEqual(ifType
, kSCValNetInterfaceType6to4
)) {
3186 if (!isA_CFString(ifDevice
)) {
3190 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
3191 kSCNetworkInterfaceType6to4
);
3192 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeIPSec
)) {
3193 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
3194 kSCNetworkInterfaceTypeIPSec
);
3195 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeLoopback
)) {
3196 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
3197 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
3198 if (CFStringFind(ifSubType
, CFSTR("."), 0).location
!= kCFNotFound
) {
3199 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
3202 } else if ((CFStringFind(ifType
, CFSTR("."), 0).location
!= kCFNotFound
) && (ifDevice
== NULL
)) {
3203 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
3207 if (matching_interfaces
!= NULL
) {
3209 SCPreferencesRef prefs
;
3211 n
= CFArrayGetCount(matching_interfaces
);
3214 interfacePrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, 0);
3215 if (_SC_CFEqual(ifUnique
, interfacePrivate
->entity_device_unique
)) {
3216 // if the unique ID's match
3217 CFRetain(interfacePrivate
);
3221 interfacePrivate
= NULL
;
3224 if (!CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
)) {
3227 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), NULL
);
3228 if (prefs
== NULL
) {
3231 if (!CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_BOND_INTERFACES_"))) {
3232 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findBondInterface(prefs
, ifDevice
);
3235 if ((interfacePrivate
== NULL
)
3236 && !CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_BRIDGE_INTERFACES_"))) {
3237 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findBridgeInterface(prefs
, ifDevice
);
3240 if ((interfacePrivate
== NULL
)
3241 && !CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_VLAN_INTERFACES_"))) {
3242 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findVLANInterface(prefs
, ifDevice
);
3247 if (ifUnique
!= NULL
) {
3250 // we are looking for an interface with a unique ID
3251 // so let's try to focus our choices
3252 for (i
= 0; i
< n
; i
++) {
3253 SCNetworkInterfacePrivateRef scanPrivate
;
3255 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
3256 if (_SC_CFEqual(ifUnique
, scanPrivate
->entity_device_unique
)) {
3257 if (interfacePrivate
!= NULL
) {
3258 // if we've matched more than one interface
3259 interfacePrivate
= NULL
;
3262 interfacePrivate
= scanPrivate
;
3265 } else if (CFDictionaryGetValueIfPresent(interface_entity
,
3266 kSCPropUserDefinedName
,
3267 (const void **)&ifName
)) {
3270 // we don't have a unique ID but do have an interface
3271 // name. If the matching interfaces do have IDs than
3272 // we can try to focus our choices using the name
3273 for (i
= 0; i
< n
; i
++) {
3274 SCNetworkInterfacePrivateRef scanPrivate
;
3276 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
3277 if (scanPrivate
->entity_device_unique
!= NULL
) {
3278 SCNetworkInterfaceRef scan
= (SCNetworkInterfaceRef
)scanPrivate
;
3279 CFStringRef scanName
;
3281 scanName
= __SCNetworkInterfaceGetNonLocalizedDisplayName(scan
);
3282 if ((scanName
!= NULL
) && !_SC_CFEqual(ifName
, scanName
)) {
3283 continue; // if not the same display name
3287 if (interfacePrivate
!= NULL
) {
3288 // if we've matched more than one interface
3289 interfacePrivate
= NULL
;
3292 interfacePrivate
= scanPrivate
;
3295 if (interfacePrivate
== NULL
) {
3296 SCLog(TRUE
, LOG_ERR
, CFSTR("_SCNetworkInterfaceCreateWithEntity() failed, more than one interface matches %@"), ifDevice
);
3297 interfacePrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, 0);
3299 CFRetain(interfacePrivate
);
3302 CFRelease(matching_interfaces
);
3307 if (interfacePrivate
== NULL
) {
3309 * if device not present on this system
3311 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
, NULL
);
3312 interfacePrivate
->entity_type
= ifType
;
3313 interfacePrivate
->entity_subtype
= ifSubType
;
3314 interfacePrivate
->entity_device
= (ifDevice
!= NULL
) ? CFStringCreateCopy(NULL
, ifDevice
) : NULL
;
3315 interfacePrivate
->entity_device_unique
= (ifUnique
!= NULL
) ? CFStringCreateCopy(NULL
, ifUnique
) : NULL
;
3317 if (CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
)) {
3318 CFStringRef entity_hardware
;
3320 entity_hardware
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceHardware
);
3321 if (isA_CFString((entity_hardware
)) &&
3322 CFEqual(entity_hardware
, kSCEntNetAirPort
)) {
3323 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
3324 interfacePrivate
->localized_key
= CFSTR("airport");
3325 interfacePrivate
->sort_order
= kSortAirPort
;
3329 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
3331 name
= CFDictionaryGetValue(interface_entity
, kSCPropUserDefinedName
);
3332 if (_SCNetworkInterfaceMatchesName(name
, CFSTR("iPhone"))) {
3333 interfacePrivate
->localized_key
= CFSTR("iPhone");
3334 interfacePrivate
->sort_order
= kSortTethered
;
3335 } else if (_SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-gn"))) {
3336 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-gn");
3337 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
3338 } else if (_SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-nap"))) {
3339 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-nap");
3340 interfacePrivate
->sort_order
= kSortBluetoothPAN_NAP
;
3341 } else if (_SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-u"))) {
3342 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-u");
3343 interfacePrivate
->sort_order
= kSortBluetoothPAN_U
;
3345 interfacePrivate
->sort_order
= kSortEthernet
;
3348 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeFireWire
)) {
3349 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeFireWire
;
3350 interfacePrivate
->sort_order
= kSortFireWire
;
3351 } else if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
3352 if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPoE
)) {
3353 CFStringRef entity_hardware
;
3355 entity_hardware
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceHardware
);
3356 if (isA_CFString((entity_hardware
)) &&
3357 CFEqual(entity_hardware
, kSCEntNetAirPort
)) {
3358 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
3359 interfacePrivate
->sort_order
= kSortAirPort
;
3361 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
3362 interfacePrivate
->sort_order
= kSortEthernet
;
3364 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPSerial
)) {
3365 if (CFStringHasPrefix(ifDevice
, CFSTR("Bluetooth"))) {
3366 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBluetooth
;
3367 interfacePrivate
->sort_order
= kSortBluetooth
;
3368 } else if (CFStringHasPrefix(ifDevice
, CFSTR("irda"))) {
3369 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIrDA
;
3370 interfacePrivate
->sort_order
= kSortIrDA
;
3371 } else if (CFStringHasPrefix(ifDevice
, CFSTR("wwan"))) {
3372 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeWWAN
;
3373 interfacePrivate
->sort_order
= kSortWWAN
;
3375 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeModem
;
3376 interfacePrivate
->sort_order
= kSortModem
;
3379 SCNetworkInterfaceRef child
;
3382 CFRelease(interfacePrivate
);
3383 child
= SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
, ifSubType
);
3384 interfacePrivate
= (SCNetworkInterfacePrivateRef
)child
;
3385 if (interfacePrivate
== NULL
) {
3389 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
3390 SCNetworkInterfaceRef child
;
3392 CFRelease(interfacePrivate
);
3393 child
= SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
, ifSubType
);
3394 interfacePrivate
= (SCNetworkInterfacePrivateRef
)child
;
3395 if (interfacePrivate
== NULL
) {
3398 } else if (CFStringFind(ifType
, CFSTR("."), 0).location
!= kCFNotFound
) {
3399 // if vendor interface
3400 if (vendor_interface_types
== NULL
) {
3401 vendor_interface_types
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
3403 CFSetAddValue(vendor_interface_types
, ifType
);
3405 interfacePrivate
->interface_type
= CFSetGetValue(vendor_interface_types
, ifType
);
3407 // if unknown interface
3408 CFRelease(interfacePrivate
);
3409 interfacePrivate
= NULL
;
3413 if (CFDictionaryContainsKey(interface_entity
, kSCNetworkInterfaceHiddenConfigurationKey
)) {
3414 interfacePrivate
->hidden
= TRUE
;
3418 if (service
!= NULL
) {
3419 __SCNetworkInterfaceSetService((SCNetworkInterfaceRef
)interfacePrivate
,
3422 // set prefs & serviceID to Bond member interfaces
3423 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBond
)) {
3428 members
= SCBondInterfaceGetMemberInterfaces((SCNetworkInterfaceRef
)interfacePrivate
);
3429 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
3430 for (i
= 0; i
< n
; i
++) {
3431 SCNetworkInterfaceRef member
;
3433 member
= CFArrayGetValueAtIndex(members
, i
);
3434 __SCNetworkInterfaceSetService(member
, service
);
3438 // set prefs & serviceID to Bridge member interfaces
3439 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBridge
)) {
3444 members
= SCBridgeInterfaceGetMemberInterfaces((SCNetworkInterfaceRef
)interfacePrivate
);
3445 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
3446 for (i
= 0; i
< n
; i
++) {
3447 SCNetworkInterfaceRef member
;
3449 member
= CFArrayGetValueAtIndex(members
, i
);
3450 __SCNetworkInterfaceSetService(member
, service
);
3454 // set prefs & serviceID to VLAN pyhsical interface
3455 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeVLAN
)) {
3456 SCNetworkInterfaceRef vlan_physical
;
3458 vlan_physical
= SCVLANInterfaceGetPhysicalInterface((SCNetworkInterfaceRef
)interfacePrivate
);
3459 if (vlan_physical
!= NULL
) {
3460 __SCNetworkInterfaceSetService(vlan_physical
, service
);
3465 if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
3466 SCNetworkInterfaceRef parent
;
3469 parent
= SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef
)interfacePrivate
,
3470 kSCNetworkInterfaceTypePPP
);
3471 CFRelease(interfacePrivate
);
3472 interfacePrivate
= (SCNetworkInterfacePrivateRef
)parent
;
3473 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
3474 SCNetworkInterfaceRef parent
;
3477 parent
= SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef
)interfacePrivate
,
3478 kSCNetworkInterfaceTypeVPN
);
3479 CFRelease(interfacePrivate
);
3480 interfacePrivate
= (SCNetworkInterfacePrivateRef
)parent
;
3483 return (SCNetworkInterfaceRef
)interfacePrivate
;
3488 #pragma mark SCNetworkInterface APIs
3493 __SCNetworkInterfaceCopyAll_IONetworkInterface(void)
3495 CFDictionaryRef matching
;
3496 CFArrayRef new_interfaces
;
3498 // get Ethernet, Firewire, and AirPort interfaces
3500 matching
= IOServiceMatching(kIONetworkInterfaceClass
);
3501 new_interfaces
= findMatchingInterfaces(matching
, processNetworkInterface
);
3502 CFRelease(matching
);
3504 return new_interfaces
;
3510 __SCNetworkInterfaceCopyAll_Modem()
3512 CFDictionaryRef matching
;
3513 CFStringRef match_keys
[2];
3514 CFStringRef match_vals
[2];
3515 CFArrayRef new_interfaces
;
3517 match_keys
[0] = CFSTR(kIOProviderClassKey
);
3518 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
3520 match_keys
[1] = CFSTR(kIOSerialBSDTypeKey
);
3521 match_vals
[1] = CFSTR(kIOSerialBSDModemType
);
3523 matching
= CFDictionaryCreate(NULL
,
3524 (const void **)match_keys
,
3525 (const void **)match_vals
,
3526 sizeof(match_keys
)/sizeof(match_keys
[0]),
3527 &kCFTypeDictionaryKeyCallBacks
,
3528 &kCFTypeDictionaryValueCallBacks
);
3529 new_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
);
3530 CFRelease(matching
);
3532 return new_interfaces
;
3538 __SCNetworkInterfaceCopyAll_RS232()
3540 CFDictionaryRef matching
;
3541 CFStringRef match_keys
[2];
3542 CFStringRef match_vals
[2];
3543 CFArrayRef new_interfaces
;
3545 match_keys
[0] = CFSTR(kIOProviderClassKey
);
3546 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
3548 match_keys
[1] = CFSTR(kIOSerialBSDTypeKey
);
3549 match_vals
[1] = CFSTR(kIOSerialBSDRS232Type
);
3551 matching
= CFDictionaryCreate(NULL
,
3552 (const void **)match_keys
,
3553 (const void **)match_vals
,
3554 sizeof(match_keys
)/sizeof(match_keys
[0]),
3555 &kCFTypeDictionaryKeyCallBacks
,
3556 &kCFTypeDictionaryValueCallBacks
);
3557 new_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
);
3558 CFRelease(matching
);
3560 return new_interfaces
;
3565 add_interfaces(CFMutableArrayRef all_interfaces
, CFArrayRef new_interfaces
)
3570 n
= CFArrayGetCount(new_interfaces
);
3571 for (i
= 0; i
< n
; i
++) {
3572 CFStringRef bsdName
;
3573 SCNetworkInterfaceRef interface
;
3575 interface
= CFArrayGetValueAtIndex(new_interfaces
, i
);
3576 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
3577 if (bsdName
!= NULL
) {
3578 CFArrayAppendValue(all_interfaces
, interface
);
3587 __waitForInterfaces()
3592 SCDynamicStoreRef store
;
3594 store
= SCDynamicStoreCreate(NULL
, CFSTR("SCNetworkInterfaceCopyAll"), NULL
, NULL
);
3595 if (store
== NULL
) {
3599 key
= SCDynamicStoreKeyCreate(NULL
, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin
);
3600 keys
= CFArrayCreate(NULL
, (const void **)&key
, 1, &kCFTypeArrayCallBacks
);
3601 ok
= SCDynamicStoreSetNotificationKeys(store
, keys
, NULL
);
3604 SCLog(TRUE
, LOG_ERR
,
3605 CFSTR("SCDynamicStoreSetNotificationKeys() failed: %s"), SCErrorString(SCError()));
3610 CFArrayRef changedKeys
;
3611 CFDictionaryRef dict
;
3612 Boolean quiet
= FALSE
;
3615 dict
= SCDynamicStoreCopyValue(store
, key
);
3617 if (isA_CFDictionary(dict
) &&
3618 (CFDictionaryContainsKey(dict
, CFSTR("*QUIET*")) ||
3619 CFDictionaryContainsKey(dict
, CFSTR("*TIMEOUT*")))) {
3628 ok
= SCDynamicStoreNotifyWait(store
);
3630 SCLog(TRUE
, LOG_ERR
,
3631 CFSTR("SCDynamicStoreNotifyWait() failed: %s"), SCErrorString(SCError()));
3635 changedKeys
= SCDynamicStoreCopyNotifiedKeys(store
);
3636 if (changedKeys
!= NULL
) {
3637 CFRelease(changedKeys
);
3649 CFArrayRef
/* of SCNetworkInterfaceRef's */
3650 _SCNetworkInterfaceCopyAllWithPreferences(SCPreferencesRef prefs
)
3652 CFMutableArrayRef all_interfaces
;
3653 CFArrayRef new_interfaces
;
3654 Boolean temp_preferences
= FALSE
;
3656 /* initialize runtime */
3657 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
3659 /* wait for IOKit to quiesce */
3660 pthread_once(&iokit_quiet
, __waitForInterfaces
);
3662 all_interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3664 // get Ethernet, Firewire, and AirPort interfaces
3665 new_interfaces
= __SCNetworkInterfaceCopyAll_IONetworkInterface();
3666 if (new_interfaces
!= NULL
) {
3667 add_interfaces(all_interfaces
, new_interfaces
);
3668 CFRelease(new_interfaces
);
3671 // get Modem interfaces
3672 new_interfaces
= __SCNetworkInterfaceCopyAll_Modem();
3673 if (new_interfaces
!= NULL
) {
3674 add_interfaces(all_interfaces
, new_interfaces
);
3675 CFRelease(new_interfaces
);
3678 // get serial (RS232) interfaces
3679 new_interfaces
= __SCNetworkInterfaceCopyAll_RS232();
3680 if (new_interfaces
!= NULL
) {
3681 add_interfaces(all_interfaces
, new_interfaces
);
3682 CFRelease(new_interfaces
);
3685 // get virtual network interfaces (Bond, Bridge, VLAN)
3686 if (prefs
== NULL
) {
3687 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterfaceCopyAll"), NULL
);
3688 if (prefs
!= NULL
) {
3689 temp_preferences
= TRUE
;
3692 if (prefs
!= NULL
) {
3693 new_interfaces
= SCBondInterfaceCopyAll(prefs
);
3694 if (new_interfaces
!= NULL
) {
3695 add_interfaces(all_interfaces
, new_interfaces
);
3696 CFRelease(new_interfaces
);
3699 new_interfaces
= SCBridgeInterfaceCopyAll(prefs
);
3700 if (new_interfaces
!= NULL
) {
3701 add_interfaces(all_interfaces
, new_interfaces
);
3702 CFRelease(new_interfaces
);
3705 new_interfaces
= SCVLANInterfaceCopyAll(prefs
);
3706 if (new_interfaces
!= NULL
) {
3707 add_interfaces(all_interfaces
, new_interfaces
);
3708 CFRelease(new_interfaces
);
3711 if (temp_preferences
) CFRelease(prefs
);
3714 // all interfaces have been identified, order and return
3715 sort_interfaces(all_interfaces
);
3717 return all_interfaces
;
3721 CFArrayRef
/* of SCNetworkInterfaceRef's */
3722 SCNetworkInterfaceCopyAll()
3724 CFArrayRef all_interfaces
;
3726 all_interfaces
= _SCNetworkInterfaceCopyAllWithPreferences(NULL
);
3727 return all_interfaces
;
3731 CFArrayRef
/* of kSCNetworkInterfaceTypeXXX CFStringRef's */
3732 SCNetworkInterfaceGetSupportedInterfaceTypes(SCNetworkInterfaceRef interface
)
3735 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3737 if (!isA_SCNetworkInterface(interface
)) {
3738 _SCErrorSet(kSCStatusInvalidArgument
);
3742 if (interfacePrivate
->supported_interface_types
!= NULL
) {
3746 i
= findConfiguration(interfacePrivate
->interface_type
);
3747 if (i
!= kCFNotFound
) {
3748 if (configurations
[i
].supported_interfaces
!= doNone
) {
3749 interfacePrivate
->supported_interface_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3750 if (configurations
[i
].supported_interfaces
& do6to4
) {
3751 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceType6to4
);
3753 if (configurations
[i
].supported_interfaces
& doL2TP
) {
3754 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeL2TP
);
3756 if (configurations
[i
].supported_interfaces
& doPPP
) {
3757 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypePPP
);
3759 if (configurations
[i
].supported_interfaces
& doPPTP
) {
3760 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypePPTP
);
3762 if (configurations
[i
].supported_interfaces
& doIPSec
) {
3763 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeIPSec
);
3767 SCNetworkInterfaceRef child
;
3769 child
= SCNetworkInterfaceGetInterface(interface
);
3770 if ((child
!= NULL
) && CFEqual(child
, kSCNetworkInterfaceIPv4
)) {
3771 interfacePrivate
->supported_interface_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3772 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeVPN
);
3778 return interfacePrivate
->supported_interface_types
;
3782 CFArrayRef
/* of kSCNetworkProtocolTypeXXX CFStringRef's */
3783 SCNetworkInterfaceGetSupportedProtocolTypes(SCNetworkInterfaceRef interface
)
3786 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3788 if (!isA_SCNetworkInterface(interface
)) {
3789 _SCErrorSet(kSCStatusInvalidArgument
);
3793 if (interfacePrivate
->supported_protocol_types
!= NULL
) {
3797 i
= findConfiguration(interfacePrivate
->interface_type
);
3798 if (i
!= kCFNotFound
) {
3799 if (configurations
[i
].supported_protocols
!= doNone
) {
3800 interfacePrivate
->supported_protocol_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3801 if (configurations
[i
].supported_protocols
& doDNS
) {
3802 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeDNS
);
3804 if (configurations
[i
].supported_protocols
& doIPv4
) {
3805 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeIPv4
);
3807 if (configurations
[i
].supported_protocols
& doIPv6
) {
3808 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeIPv6
);
3810 if (configurations
[i
].supported_protocols
& doProxies
) {
3811 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeProxies
);
3813 #if !TARGET_OS_IPHONE
3814 if (configurations
[i
].supported_protocols
& doSMB
) {
3815 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeSMB
);
3817 #endif // !TARGET_OS_IPHONE
3823 return interfacePrivate
->supported_protocol_types
;
3827 SCNetworkInterfaceRef
3828 SCNetworkInterfaceCreateWithInterface(SCNetworkInterfaceRef child
, CFStringRef interfaceType
)
3830 SCNetworkInterfacePrivateRef childPrivate
= (SCNetworkInterfacePrivateRef
)child
;
3832 SCNetworkInterfacePrivateRef parentPrivate
;
3834 if (!isA_SCNetworkInterface(child
)) {
3835 _SCErrorSet(kSCStatusInvalidArgument
);
3839 if (!isA_CFString(interfaceType
)) {
3840 _SCErrorSet(kSCStatusInvalidArgument
);
3844 if (CFEqual(child
, kSCNetworkInterfaceLoopback
)) {
3845 // can't layer on top of loopback
3846 _SCErrorSet(kSCStatusInvalidArgument
);
3850 childIndex
= findConfiguration(childPrivate
->interface_type
);
3852 parentPrivate
= __SCNetworkInterfaceCreatePrivate(NULL
,
3854 childPrivate
->prefs
,
3855 childPrivate
->serviceID
,
3857 if (parentPrivate
== NULL
) {
3858 _SCErrorSet(kSCStatusFailed
);
3862 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
3863 parentPrivate
->interface_type
= kSCNetworkInterfaceTypePPP
;
3864 parentPrivate
->entity_type
= kSCValNetInterfaceTypePPP
;
3867 if (childIndex
!= kCFNotFound
) {
3868 if (configurations
[childIndex
].ppp_subtype
!= NULL
) {
3869 parentPrivate
->entity_subtype
= *configurations
[childIndex
].ppp_subtype
;
3871 // sorry, the child interface does not support PPP
3875 // if the child's interface type not known, use the child entities "Type"
3876 parentPrivate
->entity_subtype
= childPrivate
->entity_type
;
3879 if (childPrivate
->entity_device
!= NULL
) {
3880 parentPrivate
->entity_device
= CFStringCreateCopy(NULL
, childPrivate
->entity_device
);
3883 if (childPrivate
->entity_device_unique
!= NULL
) {
3884 parentPrivate
->entity_device_unique
= CFStringCreateCopy(NULL
, childPrivate
->entity_device_unique
);
3886 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
3887 if ((childIndex
== kCFNotFound
) ||
3888 ((configurations
[childIndex
].supported_interfaces
& doL2TP
) != doL2TP
)) {
3889 // if the child interface does not support L2TP
3892 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeL2TP
;
3893 parentPrivate
->localized_key
= CFSTR("l2tp");
3894 parentPrivate
->entity_type
= kSCEntNetL2TP
; // interface config goes into "L2TP"
3895 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPTP
)) {
3896 if ((childIndex
== kCFNotFound
) ||
3897 ((configurations
[childIndex
].supported_interfaces
& doPPTP
) != doPPTP
)) {
3898 // if the child interface does not support PPTP
3901 parentPrivate
->interface_type
= kSCNetworkInterfaceTypePPTP
;
3902 parentPrivate
->localized_key
= CFSTR("pptp");
3903 parentPrivate
->entity_type
= kSCEntNetPPTP
; // interface config goes into "PPTP"
3904 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceType6to4
)) {
3905 if ((childIndex
== kCFNotFound
) ||
3906 ((configurations
[childIndex
].supported_interfaces
& do6to4
) != do6to4
)) {
3907 // if the child interface does not support 6to4
3911 parentPrivate
->interface_type
= kSCNetworkInterfaceType6to4
;
3912 parentPrivate
->localized_key
= CFSTR("6to4");
3913 parentPrivate
->entity_type
= kSCValNetInterfaceType6to4
;
3914 parentPrivate
->entity_device
= CFRetain(CFSTR("stf0"));
3915 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
3916 if ((childIndex
== kCFNotFound
) ||
3917 ((configurations
[childIndex
].supported_interfaces
& doIPSec
) != doIPSec
)) {
3918 // if the child interface does not support IPSec
3921 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeIPSec
;
3922 parentPrivate
->localized_key
= CFSTR("ipsec");
3923 parentPrivate
->entity_type
= kSCValNetInterfaceTypeIPSec
;
3924 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) {
3925 if (childIndex
!= kCFNotFound
) {
3926 // if not a "vendor" child interface
3930 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeVPN
;
3931 parentPrivate
->localized_key
= CFSTR("vpn");
3932 parentPrivate
->localized_arg1
= CFRetain(childPrivate
->entity_type
);
3933 parentPrivate
->entity_type
= kSCValNetInterfaceTypeVPN
;
3934 parentPrivate
->entity_subtype
= childPrivate
->entity_type
;
3935 if (childPrivate
->entity_device
!= NULL
) {
3936 parentPrivate
->entity_device
= CFStringCreateCopy(NULL
, childPrivate
->entity_device
);
3938 if (parentPrivate
->entity_subtype
!= NULL
) {
3939 CFArrayRef components
;
3941 CFStringRef vpnType
;
3944 // the "default" interface name is derived from the VPN type
3947 // com.apple.Apple-VPN.vpnplugin --> "Apple VPN"
3950 vpnType
= parentPrivate
->entity_subtype
;
3951 components
= CFStringCreateArrayBySeparatingStrings(NULL
, vpnType
, CFSTR("."));
3952 n
= CFArrayGetCount(components
);
3954 CFEqual(CFArrayGetValueAtIndex(components
, n
- 1), CFSTR("vpnplugin"))) {
3955 CFMutableStringRef str
;
3957 str
= CFStringCreateMutableCopy(NULL
,
3959 CFArrayGetValueAtIndex(components
, n
- 2));
3960 (void) CFStringFindAndReplace(str
,
3963 CFRangeMake(0, CFStringGetLength(str
)),
3965 parentPrivate
->localized_name
= str
;
3967 CFRelease(components
);
3969 } else if (CFStringFind(interfaceType
, CFSTR("."), 0).location
!= kCFNotFound
) {
3970 // if custom interface type
3971 if (vendor_interface_types
== NULL
) {
3972 vendor_interface_types
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
3974 CFSetAddValue(vendor_interface_types
, interfaceType
);
3976 parentPrivate
->interface_type
= CFSetGetValue(vendor_interface_types
, interfaceType
);
3977 parentPrivate
->entity_type
= parentPrivate
->interface_type
; // interface config goes into a
3978 // a dictionary with the same
3979 // name as the interfaceType
3981 // unknown interface type
3985 parentPrivate
->hidden
= childPrivate
->hidden
;
3987 if (childPrivate
->overrides
!= NULL
) {
3988 parentPrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, childPrivate
->overrides
);
3991 // The following change handles the case where a user has both an Ethernet and
3992 // PPPoE network service. Because a PPPoE service is typically associated with
3993 // an ISP we want it to be sorted higher in the service order.
3994 if ((parentPrivate
->entity_subtype
!= NULL
) &&
3995 (CFEqual(parentPrivate
->entity_subtype
, kSCValNetInterfaceSubTypePPPoE
))) {
3996 if ((childPrivate
->interface_type
!= NULL
) &&
3997 (CFEqual(childPrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
))) {
3998 parentPrivate
->sort_order
= kSortAirportPPP
;
4000 parentPrivate
->sort_order
= kSortEthernetPPP
;
4003 // set sort order of the parent to match the child interface
4004 parentPrivate
->sort_order
= childPrivate
->sort_order
;
4007 return (SCNetworkInterfaceRef
)parentPrivate
;
4011 CFRelease(parentPrivate
);
4012 _SCErrorSet(kSCStatusInvalidArgument
);
4019 __SCNetworkInterfaceGetDefaultConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
)
4021 CFDictionaryRef config
= NULL
;
4022 CFStringRef defaultType
;
4023 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4025 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
4026 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4028 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
4029 if (defaultType
!= NULL
) {
4033 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
4034 SCNetworkSetGetSetID(set
), // set
4035 interfacePrivate
->entity_device
, // interface
4036 defaultType
); // entity
4038 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
4041 if (config
== NULL
) {
4042 // if the "set" does not have a saved configuration, use
4043 // the [template] "interface" configuration
4044 if (interfacePrivate
->unsaved
!= NULL
) {
4045 config
= CFDictionaryGetValue(interfacePrivate
->unsaved
, defaultType
);
4046 if (config
== (CFDictionaryRef
)kCFNull
) {
4051 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
4062 static CFDictionaryRef
4063 __SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface
,
4064 CFStringRef extendedType
)
4066 CFDictionaryRef config
= NULL
;
4067 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4070 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
4071 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4073 paths
= copyConfigurationPaths(interfacePrivate
, extendedType
);
4074 if (paths
!= NULL
) {
4077 path
= CFArrayGetValueAtIndex(paths
, 0);
4078 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
4082 if (interfacePrivate
->unsaved
!= NULL
) {
4083 config
= CFDictionaryGetValue(interfacePrivate
->unsaved
, extendedType
);
4084 if (config
== (CFDictionaryRef
)kCFNull
) {
4090 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
4099 SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface
)
4101 CFDictionaryRef config
;
4102 CFStringRef defaultType
;
4104 if (!isA_SCNetworkInterface(interface
)) {
4105 _SCErrorSet(kSCStatusInvalidArgument
);
4109 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
4110 if (defaultType
== NULL
) {
4114 config
= __SCNetworkInterfaceGetConfiguration(interface
, defaultType
);
4115 if (config
== NULL
) {
4116 if (CFEqual(defaultType
, kSCEntNetAirPort
)) {
4117 SCNetworkInterfacePrivateRef interfacePrivate
;
4120 // if AirPort interface, check for a per-service config
4121 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4122 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
4123 interfacePrivate
->serviceID
, // service
4124 kSCEntNetAirPort
); // entity
4125 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
4129 if (config
== NULL
) {
4130 _SCErrorSet(kSCStatusOK
);
4138 SCNetworkInterfaceGetExtendedConfiguration(SCNetworkInterfaceRef interface
,
4139 CFStringRef extendedType
)
4141 CFDictionaryRef config
;
4143 if (!isA_SCNetworkInterface(interface
)) {
4144 _SCErrorSet(kSCStatusInvalidArgument
);
4148 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, TRUE
)) {
4149 _SCErrorSet(kSCStatusInvalidArgument
);
4153 config
= __SCNetworkInterfaceGetConfiguration(interface
, extendedType
);
4154 if (config
== NULL
) {
4155 _SCErrorSet(kSCStatusOK
);
4163 SCNetworkInterfaceGetBSDName(SCNetworkInterfaceRef interface
)
4165 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4167 if (!isA_SCNetworkInterface(interface
)) {
4168 _SCErrorSet(kSCStatusInvalidArgument
);
4172 if ((interfacePrivate
->interface
!= NULL
) &&
4173 (interfacePrivate
->interface
!= kSCNetworkInterfaceIPv4
)) {
4174 _SCErrorSet(kSCStatusOK
);
4178 return interfacePrivate
->entity_device
;
4183 SCNetworkInterfaceGetHardwareAddressString(SCNetworkInterfaceRef interface
)
4185 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4187 if (!isA_SCNetworkInterface(interface
)) {
4188 _SCErrorSet(kSCStatusInvalidArgument
);
4192 if ((interfacePrivate
->address
!= NULL
) &&
4193 (interfacePrivate
->addressString
== NULL
)) {
4197 char mac
[sizeof("xx:xx:xx:xx:xx:xx:xx:xx")];
4200 bp
= (uint8_t *)CFDataGetBytePtr(interfacePrivate
->address
);
4201 n
= CFDataGetLength(interfacePrivate
->address
) * 3;
4203 if (n
> sizeof(mac
)) {
4204 mac_p
= CFAllocatorAllocate(NULL
, 0, n
);
4207 for (cp
= mac_p
; n
> 0; n
-= 3) {
4208 cp
+= snprintf(cp
, n
, "%2.2x:", *bp
++);
4211 interfacePrivate
->addressString
= CFStringCreateWithCString(NULL
, mac_p
, kCFStringEncodingUTF8
);
4212 if (mac_p
!= mac
) CFAllocatorDeallocate(NULL
, mac_p
);
4215 return interfacePrivate
->addressString
;
4219 SCNetworkInterfaceRef
4220 SCNetworkInterfaceGetInterface(SCNetworkInterfaceRef interface
)
4222 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4224 if (!isA_SCNetworkInterface(interface
)) {
4225 _SCErrorSet(kSCStatusInvalidArgument
);
4229 return interfacePrivate
->interface
;
4234 SCNetworkInterfaceGetInterfaceType(SCNetworkInterfaceRef interface
)
4236 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4238 if (!isA_SCNetworkInterface(interface
)) {
4239 _SCErrorSet(kSCStatusInvalidArgument
);
4243 return interfacePrivate
->interface_type
;
4248 copy_interface_string(CFBundleRef bundle
, CFStringRef key
, Boolean localized
)
4250 CFStringRef str
= NULL
;
4253 str
= CFBundleCopyLocalizedString(bundle
,
4256 NETWORKINTERFACE_LOCALIZATIONS
);
4258 str
= _SC_CFBundleCopyNonLocalizedString(bundle
,
4261 NETWORKINTERFACE_LOCALIZATIONS
);
4269 copy_display_name(SCNetworkInterfaceRef interface
, Boolean localized
, Boolean oldLocalization
)
4271 CFMutableStringRef local
;
4274 local
= CFStringCreateMutable(NULL
, 0);
4276 while (interface
!= NULL
) {
4277 Boolean added
= FALSE
;
4278 SCNetworkInterfaceRef child
= NULL
;
4279 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4281 if ((interfacePrivate
->interface
!= NULL
) &&
4282 (interfacePrivate
->interface
!= kSCNetworkInterfaceIPv4
) &&
4283 !CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeVPN
)) {
4284 child
= interfacePrivate
->interface
;
4287 if ((bundle
!= NULL
) && (interfacePrivate
->localized_key
!= NULL
)) {
4289 CFStringRef key
= interfacePrivate
->localized_key
;
4291 if (oldLocalization
) {
4292 key
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("X-%@"),
4293 interfacePrivate
->localized_key
);
4295 fmt
= copy_interface_string(bundle
, key
, localized
);
4297 CFStringAppendFormat(local
,
4300 interfacePrivate
->localized_arg1
,
4301 interfacePrivate
->localized_arg2
);
4305 if (oldLocalization
) {
4311 (interfacePrivate
->prefs
!= NULL
) &&
4312 (interfacePrivate
->serviceID
!= NULL
) &&
4314 CFDictionaryRef entity
;
4317 // check for (and use) the name of the interface when it
4318 // was last available
4319 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,
4320 interfacePrivate
->serviceID
,
4321 kSCEntNetInterface
);
4322 entity
= SCPreferencesPathGetValue(interfacePrivate
->prefs
, path
);
4324 if (isA_CFDictionary(entity
)) {
4327 name
= CFDictionaryGetValue(entity
, kSCPropUserDefinedName
);
4328 if (isA_CFString(name
)) {
4329 CFStringAppend(local
, name
);
4336 // create (non-)localized name based on the interface type
4337 CFStringAppend(local
, interfacePrivate
->interface_type
);
4339 // ... and, if this is a leaf node, the interface device
4340 if ((interfacePrivate
->entity_device
!= NULL
) && (child
== NULL
)) {
4341 CFStringAppendFormat(local
, NULL
, CFSTR(" (%@)"), interfacePrivate
->entity_device
);
4345 if (child
!= NULL
) {
4346 // if this interface is layered over another
4347 CFStringAppend(local
, CFSTR(" --> "));
4353 name
= CFStringCreateCopy(NULL
, local
);
4360 #if !TARGET_OS_EMBEDDED && !TARGET_IPHONE_SIMULATOR
4363 __SCNetworkInterfaceCopyXLocalizedDisplayName(SCNetworkInterfaceRef interface
)
4367 if (!isA_SCNetworkInterface(interface
)) {
4368 _SCErrorSet(kSCStatusInvalidArgument
);
4372 name
= copy_display_name(interface
, TRUE
, TRUE
);
4379 __SCNetworkInterfaceCopyXNonLocalizedDisplayName(SCNetworkInterfaceRef interface
)
4381 CFStringRef localized_name
;
4383 if (!isA_SCNetworkInterface(interface
)) {
4384 _SCErrorSet(kSCStatusInvalidArgument
);
4388 localized_name
= copy_display_name(interface
, FALSE
, TRUE
);
4389 return localized_name
;
4391 #endif // !TARGET_OS_EMBEDDED && !TARGET_IPHONE_SIMULATOR
4396 __SCNetworkInterfaceGetNonLocalizedDisplayName(SCNetworkInterfaceRef interface
)
4398 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4400 if (!isA_SCNetworkInterface(interface
)) {
4401 _SCErrorSet(kSCStatusInvalidArgument
);
4405 if (interfacePrivate
->name
== NULL
) {
4406 interfacePrivate
->name
= copy_display_name(interface
, FALSE
, FALSE
);
4409 return interfacePrivate
->name
;
4414 SCNetworkInterfaceGetLocalizedDisplayName(SCNetworkInterfaceRef interface
)
4416 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4418 if (!isA_SCNetworkInterface(interface
)) {
4419 _SCErrorSet(kSCStatusInvalidArgument
);
4423 if (interfacePrivate
->localized_name
== NULL
) {
4424 interfacePrivate
->localized_name
= copy_display_name(interface
, TRUE
, FALSE
);
4427 return interfacePrivate
->localized_name
;
4433 __SCNetworkInterfaceGetTemplateOverrides(SCNetworkInterfaceRef interface
, CFStringRef overrideType
)
4435 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4436 CFDictionaryRef overrides
= NULL
;
4438 if (interfacePrivate
->overrides
!= NULL
) {
4439 overrides
= CFDictionaryGetValue(interfacePrivate
->overrides
, overrideType
);
4447 SCNetworkInterfaceGetTypeID(void)
4449 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
); /* initialize runtime */
4450 return __kSCNetworkInterfaceTypeID
;
4456 __SCNetworkInterfaceSetDefaultConfiguration(SCNetworkSetRef set
,
4457 SCNetworkInterfaceRef interface
,
4458 CFStringRef defaultType
,
4459 CFDictionaryRef config
,
4462 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4465 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
4466 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4468 if (defaultType
== NULL
) {
4469 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
4470 if (defaultType
== NULL
) {
4475 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
4482 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
4483 SCNetworkSetGetSetID(set
), // set
4484 interfacePrivate
->entity_device
, // interface
4485 defaultType
); // entity
4487 ok
= __setPrefsConfiguration(interfacePrivate
->prefs
, path
, config
, FALSE
);
4490 // if configuration has been saved
4491 if (interfacePrivate
->unsaved
!= NULL
) {
4492 CFDictionaryRemoveValue(interfacePrivate
->unsaved
, defaultType
);
4493 if (CFDictionaryGetCount(interfacePrivate
->unsaved
) == 0) {
4494 CFRelease(interfacePrivate
->unsaved
);
4495 interfacePrivate
->unsaved
= NULL
;
4501 if (config
== NULL
) {
4502 // remember that we are clearing the configuration
4503 config
= (CFDictionaryRef
)kCFNull
;
4506 if (interfacePrivate
->unsaved
== NULL
) {
4507 interfacePrivate
->unsaved
= CFDictionaryCreateMutable(NULL
,
4509 &kCFTypeDictionaryKeyCallBacks
,
4510 &kCFTypeDictionaryValueCallBacks
);
4512 CFDictionarySetValue(interfacePrivate
->unsaved
, defaultType
, config
);
4515 _SCErrorSet(kSCStatusNoKey
);
4526 __SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface
,
4527 CFStringRef extendedType
,
4528 CFDictionaryRef config
,
4531 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4535 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
4536 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4538 if (extendedType
== NULL
) {
4539 extendedType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
4540 if (extendedType
== NULL
) {
4545 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
4549 paths
= copyConfigurationPaths(interfacePrivate
, extendedType
);
4550 if (paths
!= NULL
) {
4554 n
= CFArrayGetCount(paths
);
4555 for (i
= 0; i
< n
; i
++) {
4558 path
= CFArrayGetValueAtIndex(paths
, i
);
4559 ok
= __setPrefsConfiguration(interfacePrivate
->prefs
, path
, config
, FALSE
);
4566 // if configuration has been saved
4567 if (interfacePrivate
->unsaved
!= NULL
) {
4568 CFDictionaryRemoveValue(interfacePrivate
->unsaved
, extendedType
);
4569 if (CFDictionaryGetCount(interfacePrivate
->unsaved
) == 0) {
4570 CFRelease(interfacePrivate
->unsaved
);
4571 interfacePrivate
->unsaved
= NULL
;
4579 if (config
== NULL
) {
4580 // remember that we are clearing the configuration
4581 config
= (CFDictionaryRef
)kCFNull
;
4584 if (interfacePrivate
->unsaved
== NULL
) {
4585 interfacePrivate
->unsaved
= CFDictionaryCreateMutable(NULL
,
4587 &kCFTypeDictionaryKeyCallBacks
,
4588 &kCFTypeDictionaryValueCallBacks
);
4590 CFDictionarySetValue(interfacePrivate
->unsaved
, extendedType
, config
);
4593 _SCErrorSet(kSCStatusNoKey
);
4602 SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface
, CFDictionaryRef config
)
4604 CFStringRef defaultType
;
4606 if (!isA_SCNetworkInterface(interface
)) {
4607 _SCErrorSet(kSCStatusInvalidArgument
);
4611 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
4612 if (defaultType
== NULL
) {
4616 return __SCNetworkInterfaceSetConfiguration(interface
, defaultType
, config
, FALSE
);
4621 SCNetworkInterfaceSetExtendedConfiguration(SCNetworkInterfaceRef interface
,
4622 CFStringRef extendedType
,
4623 CFDictionaryRef config
)
4625 if (!isA_SCNetworkInterface(interface
)) {
4626 _SCErrorSet(kSCStatusInvalidArgument
);
4630 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, TRUE
)) {
4634 return __SCNetworkInterfaceSetConfiguration(interface
, extendedType
, config
, FALSE
);
4639 #pragma mark SCNetworkInterface [Refresh Configuration] API
4642 #ifndef kSCEntNetRefreshConfiguration
4643 #define kSCEntNetRefreshConfiguration CFSTR("RefreshConfiguration")
4644 #endif // kSCEntNetRefreshConfiguration
4647 _SCNetworkInterfaceForceConfigurationRefresh(CFStringRef ifName
)
4651 SCDynamicStoreRef store
;
4653 if (!isA_CFString(ifName
)) {
4654 _SCErrorSet(kSCStatusInvalidArgument
);
4658 store
= SCDynamicStoreCreate(NULL
, CFSTR("_SCNetworkInterfaceForceConfigurationRefresh"), NULL
, NULL
);
4659 if (store
== NULL
) {
4663 key
= SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL
,
4664 kSCDynamicStoreDomainState
,
4666 kSCEntNetRefreshConfiguration
);
4667 ok
= SCDynamicStoreNotifyValue(store
, key
);
4675 __SCNetworkInterfaceForceConfigurationRefresh_helper(SCPreferencesRef prefs
, CFStringRef ifName
)
4677 CFDataRef data
= NULL
;
4679 SCPreferencesPrivateRef prefsPrivate
= (SCPreferencesPrivateRef
)prefs
;
4680 uint32_t status
= kSCStatusOK
;
4681 CFDataRef reply
= NULL
;
4683 if (prefsPrivate
->helper_port
== MACH_PORT_NULL
) {
4684 ok
= __SCPreferencesCreate_helper(prefs
);
4690 // serialize the interface name
4691 ok
= _SCSerializeString(ifName
, &data
, NULL
, NULL
);
4696 // have the helper "refresh" the configuration
4697 status
= kSCStatusOK
;
4699 ok
= _SCHelperExec(prefsPrivate
->helper_port
,
4700 SCHELPER_MSG_INTERFACE_REFRESH
,
4704 if (data
!= NULL
) CFRelease(data
);
4709 if (status
!= kSCStatusOK
) {
4718 if (prefsPrivate
->helper_port
!= MACH_PORT_NULL
) {
4719 _SCHelperClose(&prefsPrivate
->helper_port
);
4722 status
= kSCStatusAccessError
;
4727 _SCErrorSet(status
);
4733 SCNetworkInterfaceForceConfigurationRefresh(SCNetworkInterfaceRef interface
)
4736 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4738 if (!isA_SCNetworkInterface(interface
)) {
4739 _SCErrorSet(kSCStatusInvalidArgument
);
4743 ifName
= SCNetworkInterfaceGetBSDName(interface
);
4744 if (ifName
== NULL
) {
4745 _SCErrorSet(kSCStatusInvalidArgument
);
4749 if (interfacePrivate
->prefs
!= NULL
) {
4750 SCPreferencesRef prefs
= interfacePrivate
->prefs
;
4751 SCPreferencesPrivateRef prefsPrivate
= (SCPreferencesPrivateRef
)prefs
;
4753 if (prefsPrivate
->authorizationData
!= NULL
) {
4754 return __SCNetworkInterfaceForceConfigurationRefresh_helper(prefs
, ifName
);
4758 return _SCNetworkInterfaceForceConfigurationRefresh(ifName
);
4763 SCNetworkInterfaceRefreshConfiguration(CFStringRef ifName
)
4765 return _SCNetworkInterfaceForceConfigurationRefresh(ifName
);
4770 #pragma mark SCNetworkInterface Password APIs
4774 getPasswordID(CFDictionaryRef config
, CFStringRef serviceID
)
4776 CFStringRef unique_id
= NULL
;
4778 if (config
!= NULL
) {
4779 CFStringRef encryption
;
4781 encryption
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPasswordEncryption
);
4782 if (isA_CFString(encryption
) &&
4783 CFEqual(encryption
, kSCValNetPPPAuthPasswordEncryptionKeychain
)) {
4784 unique_id
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPassword
);
4787 if (unique_id
== NULL
) {
4788 unique_id
= serviceID
;
4796 copySharedSecretID(CFDictionaryRef config
, CFStringRef serviceID
)
4798 CFMutableStringRef shared_id
= NULL
;
4800 if (config
!= NULL
) {
4801 CFStringRef encryption
;
4803 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecretEncryption
);
4804 if (isA_CFString(encryption
) &&
4805 CFEqual(encryption
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) {
4806 shared_id
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecret
);
4807 if (shared_id
!= NULL
) {
4808 CFRetain(shared_id
);
4813 if (shared_id
== NULL
) {
4814 CFStringRef unique_id
;
4816 unique_id
= getPasswordID(config
, serviceID
);
4817 shared_id
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
4818 CFStringAppend(shared_id
, CFSTR(".SS"));
4826 copyXAuthID(CFDictionaryRef config
, CFStringRef serviceID
)
4828 CFMutableStringRef xauth_id
= NULL
;
4830 if (config
!= NULL
) {
4831 CFStringRef encryption
;
4833 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPasswordEncryption
);
4834 if (isA_CFString(encryption
) &&
4835 CFEqual(encryption
, kSCValNetIPSecXAuthPasswordEncryptionKeychain
)) {
4836 xauth_id
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPassword
);
4837 if (xauth_id
!= NULL
) {
4843 if (xauth_id
== NULL
) {
4844 CFStringRef unique_id
;
4846 unique_id
= getPasswordID(config
, serviceID
);
4847 xauth_id
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
4848 CFStringAppend(xauth_id
, CFSTR(".XAUTH"));
4856 checkInterfacePassword(SCNetworkInterfaceRef interface
,
4857 SCNetworkInterfacePasswordType passwordType
,
4858 SCPreferencesRef
*prefs
,
4859 CFStringRef
*serviceID
)
4861 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4863 if (!isA_SCNetworkInterface(interface
)) {
4867 *serviceID
= interfacePrivate
->serviceID
;
4868 if (*serviceID
== NULL
) {
4872 *prefs
= interfacePrivate
->prefs
;
4873 if (*prefs
== NULL
) {
4877 switch (passwordType
) {
4878 case kSCNetworkInterfacePasswordTypePPP
: {
4879 CFStringRef interfaceType
;
4881 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
4882 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
4890 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
4891 CFStringRef interfaceType
;
4893 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
4894 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
4895 interface
= SCNetworkInterfaceGetInterface(interface
);
4896 if (interface
!= NULL
) {
4897 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
4898 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
4899 // if PPP->L2TP interface
4903 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
4904 // if IPSec interface
4911 case kSCNetworkInterfacePasswordTypeEAPOL
: {
4915 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
4916 CFStringRef interfaceType
;
4918 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
4919 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
4920 // if IPSec interface
4927 case kSCNetworkInterfacePasswordTypeVPN
: {
4928 CFStringRef interfaceType
;
4930 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
4931 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) {
4947 _SCErrorSet(kSCStatusInvalidArgument
);
4953 SCNetworkInterfaceCheckPassword(SCNetworkInterfaceRef interface
,
4954 SCNetworkInterfacePasswordType passwordType
)
4956 Boolean exists
= FALSE
;
4957 SCPreferencesRef prefs
= NULL
;
4958 CFStringRef serviceID
= NULL
;
4960 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
4964 switch (passwordType
) {
4965 case kSCNetworkInterfacePasswordTypePPP
: {
4966 CFDictionaryRef config
;
4967 CFStringRef unique_id
;
4969 // get configuration
4970 config
= SCNetworkInterfaceGetConfiguration(interface
);
4973 unique_id
= getPasswordID(config
, serviceID
);
4976 exists
= __extract_password(prefs
,
4978 kSCPropNetPPPAuthPassword
,
4979 kSCPropNetPPPAuthPasswordEncryption
,
4980 kSCValNetPPPAuthPasswordEncryptionKeychain
,
4986 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
4987 CFDictionaryRef config
;
4989 CFStringRef shared_id
;
4991 // get configuration
4992 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
4994 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
4996 config
= SCNetworkInterfaceGetConfiguration(interface
);
4999 // get sharedSecret ID
5000 shared_id
= copySharedSecretID(config
, serviceID
);
5003 exists
= __extract_password(prefs
,
5005 kSCPropNetIPSecSharedSecret
,
5006 kSCPropNetIPSecSharedSecretEncryption
,
5007 kSCValNetIPSecSharedSecretEncryptionKeychain
,
5010 CFRelease(shared_id
);
5014 case kSCNetworkInterfacePasswordTypeEAPOL
: {
5015 CFDictionaryRef config
;
5016 CFStringRef unique_id
= NULL
;
5018 // get configuration
5019 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
5021 // get 802.1X identifier
5022 if (config
!= NULL
) {
5023 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
5025 if (!isA_CFString(unique_id
)) {
5030 exists
= _SCPreferencesSystemKeychainPasswordItemExists(prefs
, unique_id
);
5034 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
5035 CFDictionaryRef config
;
5036 CFStringRef xauth_id
;
5038 // get configuration
5039 config
= SCNetworkInterfaceGetConfiguration(interface
);
5042 xauth_id
= copyXAuthID(config
, serviceID
);
5045 exists
= __extract_password(prefs
,
5047 kSCPropNetIPSecXAuthPassword
,
5048 kSCPropNetIPSecXAuthPasswordEncryption
,
5049 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
5052 CFRelease(xauth_id
);
5056 case kSCNetworkInterfacePasswordTypeVPN
: {
5057 CFDictionaryRef config
;
5060 // get configuration
5061 config
= SCNetworkInterfaceGetConfiguration(interface
);
5064 vpn_id
= getPasswordID(config
, serviceID
);
5067 exists
= __extract_password(prefs
,
5069 kSCPropNetVPNAuthPassword
,
5070 kSCPropNetVPNAuthPasswordEncryption
,
5071 kSCValNetVPNAuthPasswordEncryptionKeychain
,
5078 _SCErrorSet(kSCStatusInvalidArgument
);
5087 SCNetworkInterfaceCopyPassword(SCNetworkInterfaceRef interface
,
5088 SCNetworkInterfacePasswordType passwordType
)
5090 CFDataRef password
= NULL
;
5091 SCPreferencesRef prefs
= NULL
;
5092 CFStringRef serviceID
= NULL
;
5094 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
5098 switch (passwordType
) {
5099 case kSCNetworkInterfacePasswordTypePPP
: {
5100 CFDictionaryRef config
;
5101 CFStringRef unique_id
;
5103 // get configuration
5104 config
= SCNetworkInterfaceGetConfiguration(interface
);
5107 unique_id
= getPasswordID(config
, serviceID
);
5110 (void) __extract_password(prefs
,
5112 kSCPropNetPPPAuthPassword
,
5113 kSCPropNetPPPAuthPasswordEncryption
,
5114 kSCValNetPPPAuthPasswordEncryptionKeychain
,
5120 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
5121 CFDictionaryRef config
;
5123 CFStringRef shared_id
;
5125 // get configuration
5126 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
5128 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
5130 config
= SCNetworkInterfaceGetConfiguration(interface
);
5133 // get sharedSecret ID
5134 shared_id
= copySharedSecretID(config
, serviceID
);
5137 (void) __extract_password(prefs
,
5139 kSCPropNetIPSecSharedSecret
,
5140 kSCPropNetIPSecSharedSecretEncryption
,
5141 kSCValNetIPSecSharedSecretEncryptionKeychain
,
5145 CFRelease(shared_id
);
5149 case kSCNetworkInterfacePasswordTypeEAPOL
: {
5150 CFDictionaryRef config
;
5151 CFStringRef unique_id
= NULL
;
5153 // get configuration
5154 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
5156 // get 802.1X identifier
5157 if (config
!= NULL
) {
5158 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
5160 if (!isA_CFString(unique_id
)) {
5161 _SCErrorSet(kSCStatusFailed
);
5166 password
= _SCPreferencesSystemKeychainPasswordItemCopy(prefs
, unique_id
);
5170 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
5171 CFDictionaryRef config
;
5172 CFStringRef xauth_id
;
5174 // get configuration
5175 config
= SCNetworkInterfaceGetConfiguration(interface
);
5178 xauth_id
= copyXAuthID(config
, serviceID
);
5181 (void) __extract_password(prefs
,
5183 kSCPropNetIPSecXAuthPassword
,
5184 kSCPropNetIPSecXAuthPasswordEncryption
,
5185 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
5188 CFRelease(xauth_id
);
5192 case kSCNetworkInterfacePasswordTypeVPN
: {
5193 CFDictionaryRef config
;
5196 // get configuration
5197 config
= SCNetworkInterfaceGetConfiguration(interface
);
5200 vpn_id
= getPasswordID(config
, serviceID
);
5203 (void) __extract_password(prefs
,
5205 kSCPropNetVPNAuthPassword
,
5206 kSCPropNetVPNAuthPasswordEncryption
,
5207 kSCValNetVPNAuthPasswordEncryptionKeychain
,
5214 _SCErrorSet(kSCStatusInvalidArgument
);
5223 SCNetworkInterfaceRemovePassword(SCNetworkInterfaceRef interface
,
5224 SCNetworkInterfacePasswordType passwordType
)
5227 SCPreferencesRef prefs
= NULL
;
5228 CFStringRef serviceID
= NULL
;
5230 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
5234 switch (passwordType
) {
5235 case kSCNetworkInterfacePasswordTypePPP
: {
5236 CFDictionaryRef config
;
5237 CFDictionaryRef newConfig
= NULL
;
5238 CFStringRef unique_id
;
5240 // get configuration
5241 config
= SCNetworkInterfaceGetConfiguration(interface
);
5244 unique_id
= getPasswordID(config
, serviceID
);
5247 ok
= __remove_password(prefs
,
5249 kSCPropNetPPPAuthPassword
,
5250 kSCPropNetPPPAuthPasswordEncryption
,
5251 kSCValNetPPPAuthPasswordEncryptionKeychain
,
5255 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
5256 if (newConfig
!= NULL
) CFRelease(newConfig
);
5262 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
5263 CFDictionaryRef config
;
5265 CFDictionaryRef newConfig
= NULL
;
5266 CFStringRef shared_id
;
5268 // get configuration
5269 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
5271 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
5273 config
= SCNetworkInterfaceGetConfiguration(interface
);
5276 // get sharedSecret ID
5277 shared_id
= copySharedSecretID(config
, serviceID
);
5280 ok
= __remove_password(prefs
,
5282 kSCPropNetIPSecSharedSecret
,
5283 kSCPropNetIPSecSharedSecretEncryption
,
5284 kSCValNetIPSecSharedSecretEncryptionKeychain
,
5289 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
5293 ok
= SCNetworkInterfaceSetConfiguration(interface
,
5296 if (newConfig
!= NULL
) CFRelease(newConfig
);
5299 CFRelease(shared_id
);
5303 case kSCNetworkInterfacePasswordTypeEAPOL
: {
5304 CFDictionaryRef config
;
5305 CFStringRef unique_id
= NULL
;
5307 // get configuration
5308 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
5310 // get 802.1X identifier
5311 if (config
!= NULL
) {
5312 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
5314 if (!isA_CFString(unique_id
)) {
5315 _SCErrorSet(kSCStatusFailed
);
5320 ok
= _SCPreferencesSystemKeychainPasswordItemRemove(prefs
, unique_id
);
5324 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
5325 CFDictionaryRef config
;
5326 CFDictionaryRef newConfig
= NULL
;
5327 CFStringRef xauth_id
;
5329 // get configuration
5330 config
= SCNetworkInterfaceGetConfiguration(interface
);
5333 xauth_id
= copyXAuthID(config
, serviceID
);
5336 ok
= __remove_password(prefs
,
5338 kSCPropNetIPSecXAuthPassword
,
5339 kSCPropNetIPSecXAuthPasswordEncryption
,
5340 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
5344 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
5345 if (newConfig
!= NULL
) CFRelease(newConfig
);
5348 CFRelease(xauth_id
);
5352 case kSCNetworkInterfacePasswordTypeVPN
: {
5353 CFDictionaryRef config
;
5354 CFDictionaryRef newConfig
= NULL
;
5357 // get configuration
5358 config
= SCNetworkInterfaceGetConfiguration(interface
);
5361 vpn_id
= getPasswordID(config
, serviceID
);
5364 ok
= __remove_password(prefs
,
5366 kSCPropNetVPNAuthPassword
,
5367 kSCPropNetVPNAuthPasswordEncryption
,
5368 kSCValNetVPNAuthPasswordEncryptionKeychain
,
5372 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
5373 if (newConfig
!= NULL
) CFRelease(newConfig
);
5379 _SCErrorSet(kSCStatusInvalidArgument
);
5388 SCNetworkInterfaceSetPassword(SCNetworkInterfaceRef interface
,
5389 SCNetworkInterfacePasswordType passwordType
,
5391 CFDictionaryRef options
)
5393 CFStringRef account
= NULL
;
5394 CFDictionaryRef config
;
5395 CFStringRef description
= NULL
;
5396 CFStringRef label
= NULL
;
5398 SCPreferencesRef prefs
= NULL
;
5399 CFStringRef serviceID
= NULL
;
5401 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
5405 switch (passwordType
) {
5406 case kSCNetworkInterfacePasswordTypePPP
: {
5407 SCNetworkServiceRef service
= NULL
;
5408 CFStringRef unique_id
;
5410 // get configuration
5411 config
= SCNetworkInterfaceGetConfiguration(interface
);
5414 unique_id
= getPasswordID(config
, serviceID
);
5416 // get "Account", "Name", "Kind"
5417 if (config
!= NULL
) {
5418 // auth name --> keychain "Account"
5419 account
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthName
);
5421 // PPP [user defined] "name" --> keychain "Name"
5422 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
5425 if (label
== NULL
) {
5426 // service name --> keychain "Name"
5427 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
5432 label
= SCNetworkServiceGetName(service
);
5433 if (label
== NULL
) {
5434 // interface name --> keychain "Name"
5435 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
5439 if (bundle
!= NULL
) {
5440 // "PPP Password" --> keychain "Kind"
5441 description
= CFBundleCopyLocalizedString(bundle
,
5442 CFSTR("KEYCHAIN_KIND_PPP_PASSWORD"),
5443 CFSTR("PPP Password"),
5448 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
5450 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
5451 (description
!= NULL
) ? description
: CFSTR("PPP Password"),
5456 CFMutableDictionaryRef newConfig
;
5458 if (config
!= NULL
) {
5459 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
5461 newConfig
= CFDictionaryCreateMutable(NULL
,
5463 &kCFTypeDictionaryKeyCallBacks
,
5464 &kCFTypeDictionaryValueCallBacks
);
5466 CFDictionarySetValue(newConfig
,
5467 kSCPropNetPPPAuthPassword
,
5469 CFDictionarySetValue(newConfig
,
5470 kSCPropNetPPPAuthPasswordEncryption
,
5471 kSCValNetPPPAuthPasswordEncryptionKeychain
);
5472 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
5473 CFRelease(newConfig
);
5476 if (description
!= NULL
) CFRelease(description
);
5477 if (service
!= NULL
) CFRelease(service
);
5481 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
5482 CFDictionaryRef baseConfig
= NULL
;
5484 SCNetworkServiceRef service
= NULL
;
5485 CFStringRef shared_id
;
5487 // get configuration
5488 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
5489 config
= SCNetworkInterfaceGetConfiguration(interface
);
5491 baseConfig
= config
;
5492 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
5495 // get sharedSecret ID
5496 shared_id
= copySharedSecretID(config
, serviceID
);
5498 // get "Account", "Name", "Kind"
5499 if (config
!= NULL
) {
5500 CFStringRef localIdentifier
;
5501 CFStringRef localIdentifierType
;
5503 if (CFDictionaryGetValueIfPresent(config
,
5504 kSCPropNetIPSecLocalIdentifierType
,
5505 (const void **)&localIdentifierType
)
5506 && CFEqual(localIdentifierType
, kSCValNetIPSecLocalIdentifierTypeKeyID
)
5507 && CFDictionaryGetValueIfPresent(config
,
5508 kSCPropNetIPSecLocalIdentifier
,
5509 (const void **)&localIdentifier
)
5510 && isA_CFString(localIdentifier
)) {
5511 // local identifier --> keychain "Account"
5512 account
= localIdentifier
;
5515 // PPP [user defined] "name" --> keychain "Name"
5517 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
5519 if (baseConfig
!= NULL
) {
5520 label
= CFDictionaryGetValue(baseConfig
, kSCPropUserDefinedName
);
5525 if (label
== NULL
) {
5526 // service name --> keychain "Name"
5527 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
5532 label
= SCNetworkServiceGetName(service
);
5533 if (label
== NULL
) {
5534 // interface name --> keychain "Name"
5535 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
5539 if (bundle
!= NULL
) {
5540 // "IPSec Shared Secret" --> keychain "Kind"
5541 description
= CFBundleCopyLocalizedString(bundle
,
5542 CFSTR("KEYCHAIN_KIND_IPSEC_SHARED_SECRET"),
5543 CFSTR("IPSec Shared Secret"),
5548 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
5550 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
5551 (description
!= NULL
) ? description
: CFSTR("IPSec Shared Secret"),
5556 CFMutableDictionaryRef newConfig
= NULL
;
5558 if (config
!= NULL
) {
5559 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
5561 newConfig
= CFDictionaryCreateMutable(NULL
,
5563 &kCFTypeDictionaryKeyCallBacks
,
5564 &kCFTypeDictionaryValueCallBacks
);
5566 CFDictionarySetValue(newConfig
,
5567 kSCPropNetIPSecSharedSecret
,
5569 CFDictionarySetValue(newConfig
,
5570 kSCPropNetIPSecSharedSecretEncryption
,
5571 kSCValNetIPSecSharedSecretEncryptionKeychain
);
5573 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
5577 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
5579 CFRelease(newConfig
);
5582 if (description
!= NULL
) CFRelease(description
);
5583 if (service
!= NULL
) CFRelease(service
);
5584 CFRelease(shared_id
);
5588 case kSCNetworkInterfacePasswordTypeEAPOL
: {
5589 CFStringRef account
= NULL
;
5590 CFStringRef unique_id
= NULL
;
5592 // get configuration
5593 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
5595 // get 802.1X identifier
5596 if (config
!= NULL
) {
5597 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
5598 unique_id
= isA_CFString(unique_id
);
5600 if (unique_id
!= NULL
) {
5601 CFRetain(unique_id
);
5605 uuid
= CFUUIDCreate(NULL
);
5606 unique_id
= CFUUIDCreateString(NULL
, uuid
);
5610 // 802.1x UserName --> keychain "Account"
5611 if (config
!= NULL
) {
5612 account
= CFDictionaryGetValue(config
, kEAPClientPropUserName
);
5615 // get "Name", "Kind"
5616 if (bundle
!= NULL
) {
5617 CFStringRef interface_name
;
5619 // "Network Connection (%@)" --> keychain "Name"
5620 interface_name
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
5621 if (interface_name
!= NULL
) {
5622 CFStringRef label_fmt
;
5624 label_fmt
= CFBundleCopyLocalizedString(bundle
,
5625 CFSTR("KEYCHAIN_DESCRIPTION_EAPOL_INTERFACE"),
5626 CFSTR("Network Connection (%@)"),
5628 label
= CFStringCreateWithFormat(NULL
, NULL
, label_fmt
, interface_name
);
5629 CFRelease(label_fmt
);
5631 label
= CFBundleCopyLocalizedString(bundle
,
5632 CFSTR("KEYCHAIN_DESCRIPTION_EAPOL"),
5633 CFSTR("Network Connection"),
5637 // "802.1X Password" --> keychain "Kind"
5638 description
= CFBundleCopyLocalizedString(bundle
,
5639 CFSTR("KEYCHAIN_KIND_EAPOL"),
5640 CFSTR("802.1X Password"),
5645 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
5647 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
5648 (description
!= NULL
) ? description
: CFSTR("802.1X Password"),
5653 CFMutableDictionaryRef newConfig
= NULL
;
5655 if (config
!= NULL
) {
5656 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
5658 newConfig
= CFDictionaryCreateMutable(NULL
,
5660 &kCFTypeDictionaryKeyCallBacks
,
5661 &kCFTypeDictionaryValueCallBacks
);
5663 CFDictionarySetValue(newConfig
,
5664 kEAPClientPropUserPasswordKeychainItemID
,
5666 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
5669 CFRelease(newConfig
);
5672 CFRelease(unique_id
);
5673 if (label
!= NULL
) CFRelease(label
);
5674 if (description
!= NULL
) CFRelease(description
);
5678 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
5679 SCNetworkServiceRef service
= NULL
;
5680 CFStringRef xauth_id
;
5682 // get configuration
5683 config
= SCNetworkInterfaceGetConfiguration(interface
);
5686 xauth_id
= copyXAuthID(config
, serviceID
);
5688 // get "Account", "Name", "Kind"
5689 if (config
!= NULL
) {
5690 // auth name --> keychain "Account"
5691 account
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthName
);
5693 // IPSec [user defined] "name" --> keychain "Name"
5694 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
5697 if (label
== NULL
) {
5698 // service name --> keychain "Name"
5699 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
5704 label
= SCNetworkServiceGetName(service
);
5705 if (label
== NULL
) {
5706 // interface name --> keychain "Name"
5707 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
5711 if (bundle
!= NULL
) {
5712 // "IPSec XAuth Password" --> keychain "Kind"
5713 description
= CFBundleCopyLocalizedString(bundle
,
5714 CFSTR("KEYCHAIN_KIND_IPSEC_XAUTH_PASSWORD"),
5715 CFSTR("IPSec XAuth Password"),
5720 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
5722 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
5723 (description
!= NULL
) ? description
: CFSTR("IPSec XAuth Password"),
5728 CFMutableDictionaryRef newConfig
;
5730 if (config
!= NULL
) {
5731 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
5733 newConfig
= CFDictionaryCreateMutable(NULL
,
5735 &kCFTypeDictionaryKeyCallBacks
,
5736 &kCFTypeDictionaryValueCallBacks
);
5738 CFDictionarySetValue(newConfig
,
5739 kSCPropNetIPSecXAuthPassword
,
5741 CFDictionarySetValue(newConfig
,
5742 kSCPropNetIPSecXAuthPasswordEncryption
,
5743 kSCValNetIPSecXAuthPasswordEncryptionKeychain
);
5744 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
5745 CFRelease(newConfig
);
5748 CFRelease(xauth_id
);
5749 if (description
!= NULL
) CFRelease(description
);
5750 if (service
!= NULL
) CFRelease(service
);
5754 case kSCNetworkInterfacePasswordTypeVPN
: {
5755 SCNetworkServiceRef service
= NULL
;
5758 // get configuration
5759 config
= SCNetworkInterfaceGetConfiguration(interface
);
5762 vpn_id
= getPasswordID(config
, serviceID
);
5764 // get "Account", "Name", "Kind"
5765 if (config
!= NULL
) {
5766 // auth name --> keychain "Account"
5767 account
= CFDictionaryGetValue(config
, kSCPropNetVPNAuthName
);
5769 // VPN [user defined] "name" --> keychain "Name"
5770 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
5773 if (label
== NULL
) {
5774 // service name --> keychain "Name"
5775 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
5780 label
= SCNetworkServiceGetName(service
);
5781 if (label
== NULL
) {
5782 // interface name --> keychain "Name"
5783 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
5787 if (bundle
!= NULL
) {
5788 // "VPN Password" --> keychain "Kind"
5789 description
= CFBundleCopyLocalizedString(bundle
,
5790 CFSTR("KEYCHAIN_KIND_VPN_PASSWORD"),
5791 CFSTR("VPN Password"),
5796 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
5798 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
5799 (description
!= NULL
) ? description
: CFSTR("VPN Password"),
5804 CFMutableDictionaryRef newConfig
;
5806 if (config
!= NULL
) {
5807 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
5809 newConfig
= CFDictionaryCreateMutable(NULL
,
5811 &kCFTypeDictionaryKeyCallBacks
,
5812 &kCFTypeDictionaryValueCallBacks
);
5814 CFDictionarySetValue(newConfig
,
5815 kSCPropNetVPNAuthPassword
,
5817 CFDictionarySetValue(newConfig
,
5818 kSCPropNetVPNAuthPasswordEncryption
,
5819 kSCValNetVPNAuthPasswordEncryptionKeychain
);
5820 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
5821 CFRelease(newConfig
);
5824 if (description
!= NULL
) CFRelease(description
);
5825 if (service
!= NULL
) CFRelease(service
);
5830 _SCErrorSet(kSCStatusInvalidArgument
);
5839 #pragma mark SCNetworkInterface [InterfaceNamer] SPIs
5843 _SCNetworkInterfaceCopyInterfaceInfo(SCNetworkInterfaceRef interface
)
5845 CFMutableDictionaryRef info
;
5846 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5849 info
= CFDictionaryCreateMutable(NULL
,
5851 &kCFTypeDictionaryKeyCallBacks
,
5852 &kCFTypeDictionaryValueCallBacks
);
5854 // add non-localized interface name
5855 name
= __SCNetworkInterfaceGetNonLocalizedDisplayName(interface
);
5857 CFDictionaryAddValue(info
, kSCPropUserDefinedName
, name
);
5861 if ((interfacePrivate
->usb
.vid
!= NULL
) || (interfacePrivate
->usb
.pid
!= NULL
)) {
5862 if (interfacePrivate
->usb
.name
!= NULL
) {
5863 CFDictionaryAddValue(info
, CFSTR(kUSBProductString
), interfacePrivate
->usb
.name
);
5865 if (interfacePrivate
->usb
.vid
!= NULL
) {
5866 CFDictionaryAddValue(info
, CFSTR(kUSBVendorID
), interfacePrivate
->usb
.vid
);
5868 if (interfacePrivate
->usb
.pid
!= NULL
) {
5869 CFDictionaryAddValue(info
, CFSTR(kUSBProductID
), interfacePrivate
->usb
.pid
);
5873 if (CFDictionaryGetCount(info
) == 0) {
5874 // do not return an empty dictionary
5883 SCNetworkInterfaceRef
5884 _SCNetworkInterfaceCreateWithIONetworkInterfaceObject(io_object_t if_obj
)
5886 SCNetworkInterfaceRef interface
= NULL
;
5888 /* initialize runtime */
5889 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5891 if (IOObjectConformsTo(if_obj
, kIONetworkInterfaceClass
)) {
5892 interface
= createInterface(if_obj
, processNetworkInterface
);
5893 } else if (IOObjectConformsTo(if_obj
, kIOSerialBSDServiceValue
)) {
5894 interface
= createInterface(if_obj
, processSerialInterface
);
5902 _SCNetworkInterfaceGetConfigurationAction(SCNetworkInterfaceRef interface
)
5904 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5906 return interfacePrivate
->configurationAction
;
5911 _SCNetworkInterfaceGetHardwareAddress(SCNetworkInterfaceRef interface
)
5913 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5915 return interfacePrivate
->address
;
5920 _SCNetworkInterfaceGetIOInterfaceType(SCNetworkInterfaceRef interface
)
5922 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5924 return interfacePrivate
->type
;
5929 _SCNetworkInterfaceGetIOInterfaceUnit(SCNetworkInterfaceRef interface
)
5931 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5933 return interfacePrivate
->unit
;
5938 _SCNetworkInterfaceGetIOPath(SCNetworkInterfaceRef interface
)
5940 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5942 return interfacePrivate
->path
;
5947 _SCNetworkInterfaceIsBuiltin(SCNetworkInterfaceRef interface
)
5949 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5951 return interfacePrivate
->builtin
;
5956 #pragma mark SCNetworkInterface SPIs
5960 _SCNetworkInterfaceCopySlashDevPath(SCNetworkInterfaceRef interface
)
5962 io_registry_entry_t device
;
5963 io_iterator_t device_iterator
= MACH_PORT_NULL
;
5964 CFStringRef device_path
= NULL
;
5965 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5967 CFStringRef match_keys
[2];
5968 CFTypeRef match_vals
[2];
5969 CFDictionaryRef match_dict
;
5970 CFDictionaryRef matching
;
5972 if (interfacePrivate
->entity_device
== NULL
) {
5976 if (interfacePrivate
->entity_device_unique
== NULL
) {
5980 match_keys
[0] = CFSTR(kIOTTYBaseNameKey
);
5981 match_vals
[0] = interfacePrivate
->entity_device
;
5982 match_dict
= CFDictionaryCreate(NULL
,
5983 (const void **)match_keys
,
5984 (const void **)match_vals
,
5986 &kCFTypeDictionaryKeyCallBacks
,
5987 &kCFTypeDictionaryValueCallBacks
);
5989 match_keys
[0] = CFSTR(kIOProviderClassKey
);
5990 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
5991 match_keys
[1] = CFSTR(kIOPropertyMatchKey
);
5992 match_vals
[1] = match_dict
;
5993 matching
= CFDictionaryCreate(NULL
,
5994 (const void **)match_keys
,
5995 (const void **)match_vals
,
5996 sizeof(match_keys
)/sizeof(match_keys
[0]),
5997 &kCFTypeDictionaryKeyCallBacks
,
5998 &kCFTypeDictionaryValueCallBacks
);
5999 CFRelease(match_dict
);
6001 // note: this "matching" dictionary will be consumed by the call to IOServiceGetMatchingServices
6002 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &device_iterator
);
6003 if (kr
!= kIOReturnSuccess
) {
6004 SCLog(TRUE
, LOG_DEBUG
, CFSTR("IOServiceGetMatchingServices() failed, kr = 0x%x"), kr
);
6008 while ((device_path
== NULL
) &&
6009 ((device
= IOIteratorNext(device_iterator
)) != MACH_PORT_NULL
)) {
6010 CFDictionaryRef overrides
;
6012 overrides
= IORegistryEntrySearchCFProperty(device
,
6014 kSCNetworkInterfaceNetworkConfigurationOverridesKey
,
6016 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
6017 if (overrides
!= NULL
) {
6018 CFDictionaryRef modemOverrides
;
6020 modemOverrides
= CFDictionaryGetValue(overrides
, kSCEntNetModem
);
6021 if (modemOverrides
!= NULL
) {
6022 CFRetain(modemOverrides
);
6024 CFRelease(overrides
);
6025 overrides
= modemOverrides
;
6027 if (overrides
== NULL
) {
6028 overrides
= IORegistryEntrySearchCFProperty(device
,
6030 CFSTR("DeviceModemOverrides"),
6032 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
6034 if (overrides
!= NULL
) {
6035 if (isA_CFDictionary(overrides
)) {
6036 CFStringRef matchIdentifier
;
6038 matchIdentifier
= CFDictionaryGetValue(overrides
, CFSTR("UniqueIdentifier"));
6039 if (isA_CFString(matchIdentifier
) &&
6040 CFEqual(interfacePrivate
->entity_device_unique
, matchIdentifier
)) {
6041 device_path
= IORegistryEntryCreateCFProperty(device
,
6042 CFSTR(kIOTTYDeviceKey
),
6047 CFRelease(overrides
);
6049 IOObjectRelease(device
);
6052 IOObjectRelease(device_iterator
);
6056 if (device_path
== NULL
) {
6057 // if we haven't found an exact match to our UniqueIdentifier
6058 // so we simply return the base name.
6059 device_path
= SCNetworkInterfaceGetBSDName(interface
);
6060 if (device_path
!= NULL
) {
6061 CFRetain(device_path
);
6070 _SCNetworkInterfaceIsBluetoothPAN(SCNetworkInterfaceRef interface
)
6072 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6074 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_GN
);
6079 _SCNetworkInterfaceIsBluetoothPAN_NAP(SCNetworkInterfaceRef interface
)
6081 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6083 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_NAP
);
6088 _SCNetworkInterfaceIsBluetoothP2P(SCNetworkInterfaceRef interface
)
6090 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6092 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_U
);
6097 _SCNetworkInterfaceIsHiddenConfiguration(SCNetworkInterfaceRef interface
)
6099 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6101 return interfacePrivate
->hidden
;
6106 _SCNetworkInterfaceIsModemV92(SCNetworkInterfaceRef interface
)
6108 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6110 return interfacePrivate
->modemIsV92
;
6115 _SCNetworkInterfaceIsTethered(SCNetworkInterfaceRef interface
)
6117 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6119 return (interfacePrivate
->sort_order
== kSortTethered
);
6124 #pragma mark SCNetworkInterface [internal] SPIs
6128 SCNetworkInterfacePrivateRef
6129 __SCNetworkInterfaceCreateCopy(CFAllocatorRef allocator
,
6130 SCNetworkInterfaceRef interface
,
6131 SCPreferencesRef prefs
,
6132 CFStringRef serviceID
)
6134 SCNetworkInterfacePrivateRef oldPrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6135 SCNetworkInterfacePrivateRef newPrivate
;
6137 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
6138 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
6140 if (interface
== kSCNetworkInterfaceIPv4
) {
6141 return (SCNetworkInterfacePrivateRef
)CFRetain(interface
);
6144 newPrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, prefs
, serviceID
, NULL
);
6145 newPrivate
->interface_type
= oldPrivate
->interface_type
;
6146 if (oldPrivate
->interface
!= NULL
) {
6147 newPrivate
->interface
= (SCNetworkInterfaceRef
)__SCNetworkInterfaceCreateCopy(NULL
, // allocator
6148 oldPrivate
->interface
, // interface
6149 prefs
, // [new] prefs
6150 serviceID
); // [new] serviceID
6152 if (oldPrivate
->name
!= NULL
) {
6153 newPrivate
->name
= CFRetain(oldPrivate
->name
);
6155 if (oldPrivate
->localized_name
!= NULL
) {
6156 newPrivate
->localized_name
= CFRetain(oldPrivate
->localized_name
);
6158 newPrivate
->localized_key
= oldPrivate
->localized_key
;
6159 if (oldPrivate
->localized_arg1
!= NULL
) {
6160 newPrivate
->localized_arg1
= CFRetain(oldPrivate
->localized_arg1
);
6162 if (oldPrivate
->localized_arg2
!= NULL
) {
6163 newPrivate
->localized_arg2
= CFRetain(oldPrivate
->localized_arg2
);
6165 if (oldPrivate
->unsaved
!= NULL
) {
6166 newPrivate
->unsaved
= CFDictionaryCreateMutableCopy(NULL
, 0, oldPrivate
->unsaved
);
6168 if (oldPrivate
->entity_device
!= NULL
) {
6169 newPrivate
->entity_device
= CFRetain(oldPrivate
->entity_device
);
6171 if (oldPrivate
->entity_device_unique
!= NULL
) {
6172 newPrivate
->entity_device_unique
= CFRetain(oldPrivate
->entity_device_unique
);
6174 newPrivate
->entity_type
= oldPrivate
->entity_type
;
6175 newPrivate
->entity_subtype
= oldPrivate
->entity_subtype
;
6176 if (oldPrivate
->supported_interface_types
!= NULL
) {
6177 newPrivate
->supported_interface_types
= CFArrayCreateMutableCopy(NULL
, 0, oldPrivate
->supported_interface_types
);
6179 if (oldPrivate
->supported_protocol_types
!= NULL
) {
6180 newPrivate
->supported_protocol_types
= CFArrayCreateMutableCopy(NULL
, 0, oldPrivate
->supported_protocol_types
);
6182 if (oldPrivate
->address
!= NULL
) {
6183 newPrivate
->address
= CFRetain(oldPrivate
->address
);
6185 newPrivate
->builtin
= oldPrivate
->builtin
;
6186 if (oldPrivate
->configurationAction
!= NULL
) {
6187 newPrivate
->configurationAction
= CFRetain(oldPrivate
->configurationAction
);
6189 newPrivate
->hidden
= oldPrivate
->hidden
;
6190 if (oldPrivate
->location
!= NULL
) {
6191 newPrivate
->location
= CFRetain(oldPrivate
->location
);
6193 if (oldPrivate
->path
!= NULL
) {
6194 newPrivate
->path
= CFRetain(oldPrivate
->path
);
6196 if (oldPrivate
->overrides
!= NULL
) {
6197 newPrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, oldPrivate
->overrides
);
6199 newPrivate
->modemIsV92
= oldPrivate
->modemIsV92
;
6200 if (oldPrivate
->type
!= NULL
) {
6201 newPrivate
->type
= CFRetain(oldPrivate
->type
);
6203 if (oldPrivate
->unit
!= NULL
) {
6204 newPrivate
->unit
= CFRetain(oldPrivate
->unit
);
6206 if (oldPrivate
->usb
.name
!= NULL
) {
6207 newPrivate
->usb
.name
= CFRetain(oldPrivate
->usb
.name
);
6209 if (oldPrivate
->usb
.vid
!= NULL
) {
6210 newPrivate
->usb
.vid
= CFRetain(oldPrivate
->usb
.vid
);
6212 if (oldPrivate
->usb
.pid
!= NULL
) {
6213 newPrivate
->usb
.pid
= CFRetain(oldPrivate
->usb
.pid
);
6215 newPrivate
->sort_order
= oldPrivate
->sort_order
;
6217 newPrivate
->supportsBond
= oldPrivate
->supportsBond
;
6218 if (oldPrivate
->bond
.interfaces
!= NULL
) {
6219 newPrivate
->bond
.interfaces
= CFRetain(oldPrivate
->bond
.interfaces
);
6221 if (oldPrivate
->bond
.mode
!= NULL
) {
6222 newPrivate
->bond
.mode
= CFRetain(oldPrivate
->bond
.mode
);
6224 if (oldPrivate
->bond
.options
!= NULL
) {
6225 newPrivate
->bond
.options
= CFRetain(oldPrivate
->bond
.options
);
6228 newPrivate
->supportsBridge
= oldPrivate
->supportsBridge
;
6229 if (oldPrivate
->bridge
.interfaces
!= NULL
) {
6230 newPrivate
->bridge
.interfaces
= CFRetain(oldPrivate
->bridge
.interfaces
);
6232 if (oldPrivate
->bridge
.options
!= NULL
) {
6233 newPrivate
->bridge
.options
= CFRetain(oldPrivate
->bridge
.options
);
6236 newPrivate
->supportsVLAN
= oldPrivate
->supportsVLAN
;
6237 if (oldPrivate
->vlan
.interface
!= NULL
) {
6238 newPrivate
->vlan
.interface
= CFRetain(oldPrivate
->vlan
.interface
);
6240 if (oldPrivate
->vlan
.tag
!= NULL
) {
6241 newPrivate
->vlan
.tag
= CFRetain(oldPrivate
->vlan
.tag
);
6243 if (oldPrivate
->vlan
.options
!= NULL
) {
6244 newPrivate
->vlan
.options
= CFRetain(oldPrivate
->vlan
.options
);
6253 __SCNetworkInterfaceCopyDeepConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
)
6255 CFMutableArrayRef configs
;
6257 configs
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
6259 while (interface
!= NULL
) {
6260 CFStringRef defaultType
;
6261 CFMutableDictionaryRef interfaceConfiguration
;
6263 interfaceConfiguration
= CFDictionaryCreateMutable(NULL
,
6265 &kCFTypeDictionaryKeyCallBacks
,
6266 &kCFTypeDictionaryValueCallBacks
);
6268 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
6269 if (defaultType
!= NULL
) {
6270 CFDictionaryRef config
;
6271 CFArrayRef extendedTypes
;
6274 config
= __SCNetworkInterfaceGetConfiguration(interface
, defaultType
);
6276 config
= __SCNetworkInterfaceGetDefaultConfiguration(set
, interface
);
6278 if (config
== NULL
) {
6279 config
= (CFDictionaryRef
)kCFNull
;
6281 CFDictionarySetValue(interfaceConfiguration
, defaultType
, config
);
6283 extendedTypes
= extendedConfigurationTypes(interface
);
6284 if (extendedTypes
!= NULL
) {
6288 n
= CFArrayGetCount(extendedTypes
);
6289 for (i
= 0; i
< n
; i
++) {
6290 CFStringRef extendedType
;
6292 extendedType
= CFArrayGetValueAtIndex(extendedTypes
, i
);
6293 config
= __SCNetworkInterfaceGetConfiguration(interface
, extendedType
);
6294 if (config
== NULL
) {
6295 config
= (CFDictionaryRef
)kCFNull
;
6297 CFDictionarySetValue(interfaceConfiguration
, extendedType
, config
);
6300 CFRelease(extendedTypes
);
6304 CFArrayAppendValue(configs
, interfaceConfiguration
);
6305 CFRelease(interfaceConfiguration
);
6307 interface
= SCNetworkInterfaceGetInterface(interface
);
6314 __private_extern__ Boolean
6315 __SCNetworkInterfaceIsMember(SCPreferencesRef prefs
, SCNetworkInterfaceRef interface
)
6317 CFArrayRef interfaces
;
6318 Boolean match
= FALSE
;
6319 CFMutableSetRef members
;
6321 members
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
6323 // add Bond [member] interfaces
6324 interfaces
= SCBondInterfaceCopyAll(prefs
);
6325 if (interfaces
!= NULL
) {
6326 __SCBondInterfaceListCollectMembers(interfaces
, members
);
6327 CFRelease(interfaces
);
6330 // add Bridge [member] interfaces
6331 interfaces
= SCBridgeInterfaceCopyAll(prefs
);
6332 if (interfaces
!= NULL
) {
6333 __SCBridgeInterfaceListCollectMembers(interfaces
, members
);
6334 CFRelease(interfaces
);
6337 if (CFSetGetCount(members
) == 0) {
6341 while (interface
!= NULL
) {
6342 match
= CFSetContainsValue(members
, interface
);
6344 // if the interface is a member of an
6345 // Ethernet Bond or Bridge
6349 interface
= SCNetworkInterfaceGetInterface(interface
);
6361 __SCNetworkInterfaceSetDeepConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
, CFArrayRef configs
)
6365 for (i
= 0; interface
!= NULL
; i
++) {
6366 CFStringRef defaultType
;
6367 CFDictionaryRef interfaceConfiguration
;
6369 interfaceConfiguration
= (configs
!= NULL
) ? CFArrayGetValueAtIndex(configs
, i
) : NULL
;
6371 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
6372 if (defaultType
!= NULL
) {
6373 CFDictionaryRef config
;
6374 CFArrayRef extendedTypes
;
6376 config
= (interfaceConfiguration
!= NULL
) ? CFDictionaryGetValue(interfaceConfiguration
, defaultType
)
6378 if (config
== (CFDictionaryRef
)kCFNull
) {
6382 // if service is not associated with the set
6383 if (!__SCNetworkInterfaceSetConfiguration(interface
, defaultType
, config
, TRUE
)) {
6384 SCLog(TRUE
, LOG_DEBUG
,
6385 CFSTR("__SCNetworkInterfaceSetDeepConfiguration __SCNetworkInterfaceSetConfiguration() failed, interface=%@, type=%@"),
6390 // apply default configuration to this set
6391 if (!__SCNetworkInterfaceSetDefaultConfiguration(set
, interface
, defaultType
, config
, TRUE
)) {
6392 SCLog(TRUE
, LOG_DEBUG
,
6393 CFSTR("__SCNetworkInterfaceSetDeepConfiguration __SCNetworkInterfaceSetDefaultConfiguration() failed, interface=%@, type=%@"),
6399 extendedTypes
= extendedConfigurationTypes(interface
);
6400 if (extendedTypes
!= NULL
) {
6404 n
= CFArrayGetCount(extendedTypes
);
6405 for (j
= 0; j
< n
; j
++) {
6406 CFStringRef extendedType
;
6408 extendedType
= CFArrayGetValueAtIndex(extendedTypes
, j
);
6409 config
= (interfaceConfiguration
!= NULL
) ? CFDictionaryGetValue(interfaceConfiguration
, extendedType
)
6411 if (config
== (CFDictionaryRef
)kCFNull
) {
6414 if (!__SCNetworkInterfaceSetConfiguration(interface
, extendedType
, config
, TRUE
)) {
6415 SCLog(TRUE
, LOG_DEBUG
,
6416 CFSTR("__SCNetworkInterfaceSetDeepConfiguration __SCNetworkInterfaceSetConfiguration() failed, interface=%@, type=%@"),
6422 CFRelease(extendedTypes
);
6426 interface
= SCNetworkInterfaceGetInterface(interface
);