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 kPCIThunderboltString
75 #define kPCIThunderboltString "PCI-Thunderbolt"
78 #ifndef kUSBProductString
79 #define kUSBProductString "USB Product Name"
82 #ifndef kIOUserEthernetInterfaceRoleKey
83 #define kIOUserEthernetInterfaceRoleKey "InterfaceRole"
87 #include <mach/mach.h>
89 #include <net/if_types.h>
90 #include <net/route.h>
91 #include <sys/param.h>
92 #include <sys/types.h>
93 #include <sys/socket.h>
95 #include <sys/sysctl.h>
97 #include <NSSystemDirectories.h>
100 static CFStringRef
copy_interface_string (CFBundleRef bundle
, CFStringRef key
, Boolean localized
);
101 static CFStringRef
__SCNetworkInterfaceCopyDescription (CFTypeRef cf
);
102 static void __SCNetworkInterfaceDeallocate (CFTypeRef cf
);
103 static Boolean
__SCNetworkInterfaceEqual (CFTypeRef cf1
, CFTypeRef cf2
);
104 static CFHashCode
__SCNetworkInterfaceHash (CFTypeRef cf
);
123 kSortBluetoothPAN_GN
,
124 kSortBluetoothPAN_NAP
,
133 const CFStringRef kSCNetworkInterfaceType6to4
= CFSTR("6to4");
134 const CFStringRef kSCNetworkInterfaceTypeBluetooth
= CFSTR("Bluetooth");
135 const CFStringRef kSCNetworkInterfaceTypeBond
= CFSTR("Bond");
136 const CFStringRef kSCNetworkInterfaceTypeBridge
= CFSTR("Bridge");
137 const CFStringRef kSCNetworkInterfaceTypeEthernet
= CFSTR("Ethernet");
138 const CFStringRef kSCNetworkInterfaceTypeFireWire
= CFSTR("FireWire");
139 const CFStringRef kSCNetworkInterfaceTypeIEEE80211
= CFSTR("IEEE80211"); // IEEE 802.11, AirPort
140 const CFStringRef kSCNetworkInterfaceTypeIPSec
= CFSTR("IPSec");
141 const CFStringRef kSCNetworkInterfaceTypeIrDA
= CFSTR("IrDA");
142 const CFStringRef kSCNetworkInterfaceTypeL2TP
= CFSTR("L2TP");
143 const CFStringRef kSCNetworkInterfaceTypeLoopback
= CFSTR("Loopback");
144 const CFStringRef kSCNetworkInterfaceTypeModem
= CFSTR("Modem");
145 const CFStringRef kSCNetworkInterfaceTypePPP
= CFSTR("PPP");
146 const CFStringRef kSCNetworkInterfaceTypePPTP
= CFSTR("PPTP");
147 const CFStringRef kSCNetworkInterfaceTypeSerial
= CFSTR("Serial");
148 const CFStringRef kSCNetworkInterfaceTypeVLAN
= CFSTR("VLAN");
149 const CFStringRef kSCNetworkInterfaceTypeVPN
= CFSTR("VPN");
150 const CFStringRef kSCNetworkInterfaceTypeWWAN
= CFSTR("WWAN");
152 const CFStringRef kSCNetworkInterfaceTypeIPv4
= CFSTR("IPv4");
154 static SCNetworkInterfacePrivate __kSCNetworkInterfaceIPv4
= {
155 INIT_CFRUNTIME_BASE(), // cfBase
156 NULL
, // interface type
158 NULL
, // localized name
159 NULL
, // localization key
160 NULL
, // localization arg1
161 NULL
, // localization arg2
162 NULL
, // [layered] interface
166 NULL
, // entity_device
167 NULL
, // entity_device_unique
169 NULL
, // entity_subtype
170 NULL
, // supported_interface_types
171 NULL
, // supported_protocol_types
173 NULL
, // addressString
175 NULL
, // configurationAction
184 { NULL
, 0, 0 }, // usb { name, vid, pid }
185 kSortUnknown
, // sort_order
186 FALSE
, // supportsBond
187 { NULL
, NULL
, NULL
}, // bond { interfaces, options, mode }
188 FALSE
, // supportsBridge
189 { NULL
, NULL
}, // bridge { interfaces, options }
190 FALSE
, // supportsVLAN
191 { NULL
, NULL
, NULL
} // vlan { interface, tag, options }
194 const SCNetworkInterfaceRef kSCNetworkInterfaceIPv4
= (SCNetworkInterfaceRef
)&__kSCNetworkInterfaceIPv4
;
196 static SCNetworkInterfacePrivate __kSCNetworkInterfaceLoopback
= {
197 INIT_CFRUNTIME_BASE(), // cfBase
198 NULL
, // interface type
200 NULL
, // localized name
201 NULL
, // localization key
202 NULL
, // localization arg1
203 NULL
, // localization arg2
204 NULL
, // [layered] interface
208 NULL
, // entity_device
209 NULL
, // entity_device_unique
211 NULL
, // entity_subtype
212 NULL
, // supported_interface_types
213 NULL
, // supported_protocol_types
215 NULL
, // addressString
217 NULL
, // configurationAction
226 { NULL
, 0, 0 }, // usb { name, vid, pid }
227 kSortUnknown
, // sort_order
228 FALSE
, // supportsBond
229 { NULL
, NULL
, NULL
}, // bond { interfaces, options, mode }
230 FALSE
, // supportsBridge
231 { NULL
, NULL
}, // bridge { interfaces, options }
232 FALSE
, // supportsVLAN
233 { NULL
, NULL
, NULL
} // vlan { interface, tag, options }
236 const SCNetworkInterfaceRef kSCNetworkInterfaceLoopback
= (SCNetworkInterfaceRef
)&__kSCNetworkInterfaceLoopback
;
238 static CFMutableSetRef vendor_interface_types
= NULL
;
241 #pragma mark SCNetworkInterface configuration details
250 #define doOverIP do6to4|doL2TP|doPPTP|doIPSec
255 #define doProxies 1<<4
256 #if !TARGET_OS_IPHONE
258 #else // !TARGET_OS_IPHONE
260 #endif // !TARGET_OS_IPHONE
262 static const struct {
263 const CFStringRef
*interface_type
;
264 const CFStringRef
*entity_hardware
;
265 Boolean per_interface_config
;
266 uint32_t supported_interfaces
;
267 const CFStringRef
*ppp_subtype
;
268 uint32_t supported_protocols
;
269 } configurations
[] = {
270 // interface type entity_hardware if config? interface types PPP sub-type interface protocols
271 // ===================================== ================= ========== =============== ======================================= =========================================
272 { &kSCNetworkInterfaceType6to4
, &kSCEntNet6to4
, FALSE
, doNone
, NULL
, doIPv6
},
273 { &kSCNetworkInterfaceTypeBluetooth
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
274 { &kSCNetworkInterfaceTypeBond
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
275 { &kSCNetworkInterfaceTypeBridge
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
276 { &kSCNetworkInterfaceTypeEthernet
, &kSCEntNetEthernet
, TRUE
, doPPP
, &kSCValNetInterfaceSubTypePPPoE
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
277 { &kSCNetworkInterfaceTypeFireWire
, &kSCEntNetFireWire
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
278 { &kSCNetworkInterfaceTypeIEEE80211
, &kSCEntNetAirPort
, TRUE
, doPPP
, &kSCValNetInterfaceSubTypePPPoE
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
279 { &kSCNetworkInterfaceTypeIPSec
, &kSCEntNetIPSec
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
280 { &kSCNetworkInterfaceTypeIrDA
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
281 { &kSCNetworkInterfaceTypeL2TP
, NULL
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypeL2TP
, doNone
},
282 { &kSCNetworkInterfaceTypeModem
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
283 { &kSCNetworkInterfaceTypePPP
, &kSCEntNetPPP
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
284 { &kSCNetworkInterfaceTypePPTP
, NULL
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPTP
, doNone
},
285 { &kSCNetworkInterfaceTypeSerial
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
286 { &kSCNetworkInterfaceTypeVLAN
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
287 { &kSCNetworkInterfaceTypeVPN
, &kSCEntNetVPN
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
288 { &kSCNetworkInterfaceTypeWWAN
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
289 // ===================================== ================= ========== =============== ======================================= =========================================
290 { &kSCNetworkInterfaceTypeLoopback
, NULL
, TRUE
, doNone
, NULL
, doIPv4
|doIPv6
},
291 // ===================================== ================= ========== =============== ======================================= =========================================
292 { &kSCNetworkInterfaceTypeIPv4
, NULL
, FALSE
, doOverIP
, NULL
, doNone
}
296 #define NETWORKINTERFACE_LOCALIZATIONS CFSTR("NetworkInterface")
297 static CFBundleRef bundle
= NULL
;
300 static CFTypeID __kSCNetworkInterfaceTypeID
= _kCFRuntimeNotATypeID
;
303 static const CFRuntimeClass __SCNetworkInterfaceClass
= {
305 "SCNetworkInterface", // className
308 __SCNetworkInterfaceDeallocate
, // dealloc
309 __SCNetworkInterfaceEqual
, // equal
310 __SCNetworkInterfaceHash
, // hash
311 NULL
, // copyFormattingDesc
312 __SCNetworkInterfaceCopyDescription
// copyDebugDesc
316 static pthread_once_t initialized
= PTHREAD_ONCE_INIT
;
317 static pthread_once_t iokit_quiet
= PTHREAD_ONCE_INIT
;
320 static mach_port_t masterPort
= MACH_PORT_NULL
;
324 __SCNetworkInterfaceCopyDescription(CFTypeRef cf
)
326 CFAllocatorRef allocator
= CFGetAllocator(cf
);
327 CFMutableStringRef result
;
328 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
330 result
= CFStringCreateMutable(allocator
, 0);
331 CFStringAppendFormat(result
, NULL
, CFSTR("<SCNetworkInterface %p [%p]> {"), cf
, allocator
);
332 CFStringAppendFormat(result
, NULL
, CFSTR("type = %@"), interfacePrivate
->interface_type
);
333 CFStringAppendFormat(result
, NULL
, CFSTR(", entity_device = %@"), interfacePrivate
->entity_device
);
334 if (interfacePrivate
->entity_device_unique
!= NULL
) {
335 CFStringAppendFormat(result
, NULL
, CFSTR("+%@"), interfacePrivate
->entity_device_unique
);
337 CFStringAppendFormat(result
, NULL
, CFSTR(", entity_type = %@"), interfacePrivate
->entity_type
);
338 if (interfacePrivate
->entity_subtype
!= NULL
) {
339 CFStringAppendFormat(result
, NULL
, CFSTR(" / %@"), interfacePrivate
->entity_subtype
);
341 if (interfacePrivate
->name
!= NULL
) {
342 CFStringAppendFormat(result
, NULL
, CFSTR(", name = %@"), interfacePrivate
->name
);
344 if (interfacePrivate
->localized_name
!= NULL
) {
345 CFStringAppendFormat(result
, NULL
, CFSTR(", name(l) = %@"), interfacePrivate
->localized_name
);
347 if (interfacePrivate
->localized_key
!= NULL
) {
348 CFStringAppendFormat(result
, NULL
, CFSTR(", name(k) = \"%@\""), interfacePrivate
->localized_key
);
349 if (interfacePrivate
->localized_arg1
!= NULL
) {
350 CFStringAppendFormat(result
, NULL
, CFSTR("+\"%@\""), interfacePrivate
->localized_arg1
);
352 if (interfacePrivate
->localized_arg2
!= NULL
) {
353 CFStringAppendFormat(result
, NULL
, CFSTR("+\"%@\""), interfacePrivate
->localized_arg2
);
357 if (interfacePrivate
->address
!= NULL
) {
362 CFStringAppendFormat(result
, NULL
, CFSTR(", address = 0x"));
364 data
= CFDataGetBytePtr(interfacePrivate
->address
);
365 dataLen
= CFDataGetLength(interfacePrivate
->address
);
366 for (i
= 0; i
< dataLen
; i
++) {
367 CFStringAppendFormat(result
, NULL
, CFSTR("%02x"), data
[i
]);
370 CFStringAppendFormat(result
, NULL
, CFSTR(", builtin = %s"), interfacePrivate
->builtin
? "TRUE" : "FALSE");
371 if (interfacePrivate
->hidden
) {
372 CFStringAppendFormat(result
, NULL
, CFSTR(", hidden = TRUE"));
374 if (interfacePrivate
->modemIsV92
) {
375 CFStringAppendFormat(result
, NULL
, CFSTR(", v.92"));
377 if (interfacePrivate
->location
!= NULL
) {
378 CFStringAppendFormat(result
, NULL
, CFSTR(", location = %@"), interfacePrivate
->location
);
380 if (interfacePrivate
->path
!= NULL
) {
381 CFStringAppendFormat(result
, NULL
, CFSTR(", path = %@"), interfacePrivate
->path
);
383 if (interfacePrivate
->entryID
!= 0) {
384 CFStringAppendFormat(result
, NULL
, CFSTR(", entryID = 0x%llx"), interfacePrivate
->entryID
);
386 if (interfacePrivate
->type
!= NULL
) {
387 CFStringAppendFormat(result
, NULL
, CFSTR(", type = %@"), interfacePrivate
->type
);
389 if (interfacePrivate
->unit
!= NULL
) {
390 CFStringAppendFormat(result
, NULL
, CFSTR(", unit = %@"), interfacePrivate
->unit
);
392 if ((interfacePrivate
->usb
.vid
!= NULL
) || (interfacePrivate
->usb
.pid
!= NULL
)) {
396 if (!isA_CFNumber(interfacePrivate
->usb
.pid
) ||
397 !CFNumberGetValue(interfacePrivate
->usb
.vid
, kCFNumberIntType
, &pid
)) {
400 if (!isA_CFNumber(interfacePrivate
->usb
.vid
) ||
401 !CFNumberGetValue(interfacePrivate
->usb
.vid
, kCFNumberIntType
, &vid
)) {
405 if (interfacePrivate
->usb
.name
!= NULL
) {
406 CFStringAppendFormat(result
, NULL
, CFSTR(", USB name = %@"),
407 interfacePrivate
->usb
.name
);
410 CFStringAppendFormat(result
, NULL
, CFSTR(", USB vid/pid = 0x%0x/0x%0x"),
411 interfacePrivate
->usb
.vid
,
412 interfacePrivate
->usb
.pid
);
414 if (interfacePrivate
->configurationAction
!= NULL
) {
415 CFStringAppendFormat(result
, NULL
, CFSTR(", action = %@"), interfacePrivate
->configurationAction
);
417 if (interfacePrivate
->overrides
!= NULL
) {
418 CFStringAppendFormat(result
, NULL
, CFSTR(", overrides = %p"), interfacePrivate
->overrides
);
420 CFStringAppendFormat(result
, NULL
, CFSTR(", order = %d"), interfacePrivate
->sort_order
);
421 if (interfacePrivate
->prefs
!= NULL
) {
422 CFStringAppendFormat(result
, NULL
, CFSTR(", prefs = %p"), interfacePrivate
->prefs
);
424 if (interfacePrivate
->serviceID
!= NULL
) {
425 CFStringAppendFormat(result
, NULL
, CFSTR(", service = %@"), interfacePrivate
->serviceID
);
427 if (interfacePrivate
->interface
!= NULL
) {
428 CFStringAppendFormat(result
, NULL
, CFSTR(", interface = %@"), interfacePrivate
->interface
);
430 if (interfacePrivate
->unsaved
!= NULL
) {
431 CFStringAppendFormat(result
, NULL
, CFSTR(", unsaved = %@"), interfacePrivate
->unsaved
);
434 if (interfacePrivate
->bond
.interfaces
!= NULL
) {
438 n
= CFArrayGetCount(interfacePrivate
->bond
.interfaces
);
439 for (i
= 0; i
< n
; i
++) {
440 SCNetworkInterfaceRef member
;
442 member
= CFArrayGetValueAtIndex(interfacePrivate
->bond
.interfaces
, i
);
443 CFStringAppendFormat(result
, NULL
,
445 (i
== 0) ? ", interfaces = " : ", ",
446 SCNetworkInterfaceGetBSDName(member
));
449 if (interfacePrivate
->bond
.mode
!= NULL
) {
450 CFStringAppendFormat(result
, NULL
, CFSTR(", mode = %@"), interfacePrivate
->bond
.mode
);
452 if (interfacePrivate
->bond
.options
!= NULL
) {
453 CFStringAppendFormat(result
, NULL
, CFSTR(", options = %@"), interfacePrivate
->bond
.options
);
456 if (interfacePrivate
->bridge
.interfaces
!= NULL
) {
460 n
= CFArrayGetCount(interfacePrivate
->bridge
.interfaces
);
461 for (i
= 0; i
< n
; i
++) {
462 SCNetworkInterfaceRef member
;
464 member
= CFArrayGetValueAtIndex(interfacePrivate
->bridge
.interfaces
, i
);
465 CFStringAppendFormat(result
, NULL
,
467 (i
== 0) ? ", interfaces = " : ", ",
468 SCNetworkInterfaceGetBSDName(member
));
471 if (interfacePrivate
->bridge
.options
!= NULL
) {
472 CFStringAppendFormat(result
, NULL
, CFSTR(", options = %@"), interfacePrivate
->bridge
.options
);
475 if (interfacePrivate
->vlan
.interface
!= NULL
) {
476 CFStringAppendFormat(result
, NULL
,
477 CFSTR(", interface = %@"),
478 SCNetworkInterfaceGetBSDName(interfacePrivate
->vlan
.interface
));
480 if (interfacePrivate
->vlan
.tag
!= NULL
) {
481 CFStringAppendFormat(result
, NULL
, CFSTR(", tag = %@"), interfacePrivate
->vlan
.tag
);
483 if (interfacePrivate
->vlan
.options
!= NULL
) {
484 CFStringAppendFormat(result
, NULL
, CFSTR(", options = %@"), interfacePrivate
->vlan
.options
);
487 CFStringAppendFormat(result
, NULL
, CFSTR("}"));
494 __SCNetworkInterfaceDeallocate(CFTypeRef cf
)
496 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
498 /* release resources */
500 if (interfacePrivate
->name
!= NULL
)
501 CFRelease(interfacePrivate
->name
);
503 if (interfacePrivate
->localized_name
!= NULL
)
504 CFRelease(interfacePrivate
->localized_name
);
506 if (interfacePrivate
->localized_arg1
!= NULL
)
507 CFRelease(interfacePrivate
->localized_arg1
);
509 if (interfacePrivate
->localized_arg2
!= NULL
)
510 CFRelease(interfacePrivate
->localized_arg2
);
512 if (interfacePrivate
->interface
!= NULL
)
513 CFRelease(interfacePrivate
->interface
);
515 if (interfacePrivate
->prefs
!= NULL
)
516 CFRelease(interfacePrivate
->prefs
);
518 if (interfacePrivate
->serviceID
!= NULL
)
519 CFRelease(interfacePrivate
->serviceID
);
521 if (interfacePrivate
->unsaved
!= NULL
)
522 CFRelease(interfacePrivate
->unsaved
);
524 if (interfacePrivate
->entity_device
!= NULL
)
525 CFRelease(interfacePrivate
->entity_device
);
527 if (interfacePrivate
->entity_device_unique
!= NULL
)
528 CFRelease(interfacePrivate
->entity_device_unique
);
530 if (interfacePrivate
->supported_interface_types
!= NULL
)
531 CFRelease(interfacePrivate
->supported_interface_types
);
533 if (interfacePrivate
->supported_protocol_types
!= NULL
)
534 CFRelease(interfacePrivate
->supported_protocol_types
);
536 if (interfacePrivate
->address
!= NULL
)
537 CFRelease(interfacePrivate
->address
);
539 if (interfacePrivate
->addressString
!= NULL
)
540 CFRelease(interfacePrivate
->addressString
);
542 if (interfacePrivate
->configurationAction
!= NULL
)
543 CFRelease(interfacePrivate
->configurationAction
);
545 if (interfacePrivate
->location
!= NULL
)
546 CFRelease(interfacePrivate
->location
);
548 if (interfacePrivate
->path
!= NULL
)
549 CFRelease(interfacePrivate
->path
);
551 if (interfacePrivate
->overrides
!= NULL
)
552 CFRelease(interfacePrivate
->overrides
);
554 if (interfacePrivate
->type
!= NULL
)
555 CFRelease(interfacePrivate
->type
);
557 if (interfacePrivate
->unit
!= NULL
)
558 CFRelease(interfacePrivate
->unit
);
560 if (interfacePrivate
->usb
.name
!= NULL
)
561 CFRelease(interfacePrivate
->usb
.name
);
563 if (interfacePrivate
->usb
.pid
!= NULL
)
564 CFRelease(interfacePrivate
->usb
.pid
);
566 if (interfacePrivate
->usb
.vid
!= NULL
)
567 CFRelease(interfacePrivate
->usb
.vid
);
569 if (interfacePrivate
->bond
.interfaces
!= NULL
)
570 CFRelease(interfacePrivate
->bond
.interfaces
);
572 if (interfacePrivate
->bond
.mode
!= NULL
)
573 CFRelease(interfacePrivate
->bond
.mode
);
575 if (interfacePrivate
->bond
.options
!= NULL
)
576 CFRelease(interfacePrivate
->bond
.options
);
578 if (interfacePrivate
->bridge
.interfaces
!= NULL
)
579 CFRelease(interfacePrivate
->bridge
.interfaces
);
581 if (interfacePrivate
->bridge
.options
!= NULL
)
582 CFRelease(interfacePrivate
->bridge
.options
);
584 if (interfacePrivate
->vlan
.interface
!= NULL
)
585 CFRelease(interfacePrivate
->vlan
.interface
);
587 if (interfacePrivate
->vlan
.tag
!= NULL
)
588 CFRelease(interfacePrivate
->vlan
.tag
);
590 if (interfacePrivate
->vlan
.options
!= NULL
)
591 CFRelease(interfacePrivate
->vlan
.options
);
598 __SCNetworkInterfaceEqual(CFTypeRef cf1
, CFTypeRef cf2
)
600 SCNetworkInterfacePrivateRef if1
= (SCNetworkInterfacePrivateRef
)cf1
;
601 SCNetworkInterfacePrivateRef if2
= (SCNetworkInterfacePrivateRef
)cf2
;
606 if (!CFEqual(if1
->interface_type
, if2
->interface_type
)) {
607 return FALSE
; // if not the same interface type
610 if (!_SC_CFEqual(if1
->entity_device
, if2
->entity_device
)) {
611 return FALSE
; // if not the same device
614 if ((if1
->entity_device_unique
!= NULL
) && (if2
->entity_device_unique
!= NULL
)) {
615 if (!_SC_CFEqual(if1
->entity_device_unique
, if2
->entity_device_unique
)) {
616 return FALSE
; // if not the same device unique identifier
618 } else if ((if1
->entity_device_unique
!= NULL
) || (if2
->entity_device_unique
!= NULL
)) {
622 name1
= __SCNetworkInterfaceGetNonLocalizedDisplayName((SCNetworkInterfaceRef
)if1
);
623 name2
= __SCNetworkInterfaceGetNonLocalizedDisplayName((SCNetworkInterfaceRef
)if2
);
624 if ((name1
!= NULL
) && (name2
!= NULL
) && !_SC_CFEqual(name1
, name2
)) {
625 return FALSE
; // if same device but not the same display name
629 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeBond
)) {
630 if (!_SC_CFEqual(if1
->bond
.interfaces
, if2
->bond
.interfaces
)) {
631 return FALSE
; // if not the same interfaces
633 if (!_SC_CFEqual(if1
->bond
.mode
, if2
->bond
.mode
)) {
634 return FALSE
; // if not the same mode
638 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeBridge
)) {
639 if (!_SC_CFEqual(if1
->bridge
.interfaces
, if2
->bridge
.interfaces
)) {
640 return FALSE
; // if not the same interfaces
644 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeVLAN
)) {
645 if (!_SC_CFEqual(if1
->vlan
.interface
, if2
->vlan
.interface
)) {
646 return FALSE
; // if not the same physical interface
648 if (!_SC_CFEqual(if1
->vlan
.tag
, if2
->vlan
.tag
)) {
649 return FALSE
; // if not the same tag
653 if (!_SC_CFEqual(if1
->interface
, if2
->interface
)) {
654 return FALSE
; // if not the same layering
662 __SCNetworkInterfaceHash(CFTypeRef cf
)
665 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
667 if (interfacePrivate
->entity_device
!= NULL
) {
668 if (interfacePrivate
->entity_device_unique
== NULL
) {
669 hash
= CFHash(interfacePrivate
->entity_device
);
673 str
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@+%@"),
674 interfacePrivate
->entity_device
,
675 interfacePrivate
->entity_device_unique
);
686 __SCNetworkInterfaceInitialize(void)
691 __kSCNetworkInterfaceTypeID
= _CFRuntimeRegisterClass(&__SCNetworkInterfaceClass
);
693 // initialize __kSCNetworkInterfaceIPv4
694 _CFRuntimeInitStaticInstance(&__kSCNetworkInterfaceIPv4
, __kSCNetworkInterfaceTypeID
);
695 __kSCNetworkInterfaceIPv4
.interface_type
= kSCNetworkInterfaceTypeIPv4
;
696 __kSCNetworkInterfaceIPv4
.localized_key
= CFSTR("ipv4");
698 // initialize __kSCNetworkInterfaceLoopback
699 _CFRuntimeInitStaticInstance(&__kSCNetworkInterfaceLoopback
, __kSCNetworkInterfaceTypeID
);
700 __kSCNetworkInterfaceLoopback
.interface_type
= kSCNetworkInterfaceTypeLoopback
;
701 __kSCNetworkInterfaceLoopback
.localized_key
= CFSTR("loopback");
702 __kSCNetworkInterfaceLoopback
.entity_device
= CFRetain(CFSTR("lo0"));
703 __kSCNetworkInterfaceLoopback
.entity_type
= kSCValNetInterfaceTypeLoopback
;
705 // get CFBundleRef for SystemConfiguration.framework
706 bundle
= _SC_CFBundleGet();
708 // get mach port used to communication with IOKit
709 kr
= IOMasterPort(MACH_PORT_NULL
, &masterPort
);
710 if (kr
!= KERN_SUCCESS
) {
711 SCLog(TRUE
, LOG_DEBUG
,
712 CFSTR("__SCNetworkInterfaceInitialize(), could not get IOMasterPort, kr = 0x%x"),
721 SCNetworkInterfacePrivateRef
722 __SCNetworkInterfaceCreatePrivate(CFAllocatorRef allocator
,
723 SCNetworkInterfaceRef interface
,
724 SCPreferencesRef prefs
,
725 CFStringRef serviceID
)
727 SCNetworkInterfacePrivateRef interfacePrivate
;
730 /* initialize runtime */
731 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
733 /* allocate target */
734 size
= sizeof(SCNetworkInterfacePrivate
) - sizeof(CFRuntimeBase
);
735 interfacePrivate
= (SCNetworkInterfacePrivateRef
)_CFRuntimeCreateInstance(allocator
,
736 __kSCNetworkInterfaceTypeID
,
739 if (interfacePrivate
== NULL
) {
743 interfacePrivate
->interface_type
= NULL
;
744 interfacePrivate
->name
= NULL
;
745 interfacePrivate
->localized_name
= NULL
;
746 interfacePrivate
->localized_key
= NULL
;
747 interfacePrivate
->localized_arg1
= NULL
;
748 interfacePrivate
->localized_arg2
= NULL
;
749 interfacePrivate
->interface
= (interface
!= NULL
) ? CFRetain(interface
) : NULL
;
750 interfacePrivate
->prefs
= (prefs
!= NULL
) ? CFRetain(prefs
) : NULL
;
751 interfacePrivate
->serviceID
= (serviceID
!= NULL
) ? CFRetain(serviceID
) : NULL
;
752 interfacePrivate
->unsaved
= NULL
;
753 interfacePrivate
->entity_device
= NULL
;
754 interfacePrivate
->entity_device_unique
= NULL
;
755 interfacePrivate
->entity_type
= NULL
;
756 interfacePrivate
->entity_subtype
= NULL
;
757 interfacePrivate
->supported_interface_types
= NULL
;
758 interfacePrivate
->supported_protocol_types
= NULL
;
759 interfacePrivate
->address
= NULL
;
760 interfacePrivate
->addressString
= NULL
;
761 interfacePrivate
->builtin
= FALSE
;
762 interfacePrivate
->configurationAction
= NULL
;
763 interfacePrivate
->hidden
= FALSE
;
764 interfacePrivate
->location
= NULL
;
765 interfacePrivate
->path
= NULL
;
766 interfacePrivate
->entryID
= 0;
767 interfacePrivate
->overrides
= NULL
;
768 interfacePrivate
->modemIsV92
= FALSE
;
769 interfacePrivate
->type
= NULL
;
770 interfacePrivate
->unit
= NULL
;
771 interfacePrivate
->usb
.name
= NULL
;
772 interfacePrivate
->usb
.vid
= NULL
;
773 interfacePrivate
->usb
.pid
= NULL
;
774 interfacePrivate
->sort_order
= kSortUnknown
;
776 interfacePrivate
->supportsBond
= FALSE
;
777 interfacePrivate
->bond
.interfaces
= NULL
;
778 interfacePrivate
->bond
.mode
= NULL
;
779 interfacePrivate
->bond
.options
= NULL
;
781 interfacePrivate
->supportsBridge
= FALSE
;
782 interfacePrivate
->bridge
.interfaces
= NULL
;
783 interfacePrivate
->bridge
.options
= NULL
;
785 interfacePrivate
->supportsVLAN
= FALSE
;
786 interfacePrivate
->vlan
.interface
= NULL
;
787 interfacePrivate
->vlan
.tag
= NULL
;
788 interfacePrivate
->vlan
.options
= NULL
;
790 return interfacePrivate
;
796 __SCNetworkInterfaceSupportsVLAN(CFStringRef bsd_if
)
800 struct if_msghdr
* ifm
;
801 char * if_name
= NULL
;
802 unsigned int if_index
;
804 Boolean vlanOK
= FALSE
;
806 // get the interface index
807 if_name
= _SC_cfstring_to_cstring(bsd_if
, NULL
, 0, kCFStringEncodingASCII
);
808 if (if_name
== NULL
) {
809 return FALSE
; // if conversion error
811 if_index
= if_nametoindex(if_name
);
813 goto done
; // if unknown interface
816 // get information for the specified interface
821 mib
[4] = NET_RT_IFLIST
;
822 mib
[5] = if_index
; /* ask for exactly one interface */
824 if (sysctl(mib
, 6, NULL
, &buf_len
, NULL
, 0) == -1) {
825 SCLog(TRUE
, LOG_ERR
, CFSTR("sysctl() size failed: %s"), strerror(errno
));
828 buf
= CFAllocatorAllocate(NULL
, buf_len
, 0);
829 if (sysctl(mib
, 6, buf
, &buf_len
, NULL
, 0) == -1) {
830 SCLog(TRUE
, LOG_ERR
, CFSTR("sysctl() failed: %s"), strerror(errno
));
834 // check the link type and hwassist flags
835 ifm
= (struct if_msghdr
*)buf
;
836 switch (ifm
->ifm_type
) {
838 #if defined(IF_HWASSIST_VLAN_TAGGING) && defined(IF_HWASSIST_VLAN_MTU)
839 struct if_data
*if_data
= &ifm
->ifm_data
;
841 if (if_data
->ifi_hwassist
& (IF_HWASSIST_VLAN_TAGGING
| IF_HWASSIST_VLAN_MTU
)) {
851 if (if_name
!= NULL
) CFAllocatorDeallocate(NULL
, if_name
);
852 if (buf
!= NULL
) CFAllocatorDeallocate(NULL
, buf
);
859 SCNetworkInterfacePrivateRef
860 _SCBondInterfaceCreatePrivate(CFAllocatorRef allocator
,
863 SCNetworkInterfacePrivateRef interfacePrivate
;
865 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
);
866 if (interfacePrivate
== NULL
) {
870 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBond
;
871 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
872 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, bond_if
);
873 interfacePrivate
->builtin
= TRUE
;
874 interfacePrivate
->supportsVLAN
= __SCNetworkInterfaceSupportsVLAN(bond_if
);
875 interfacePrivate
->sort_order
= kSortBond
;
877 interfacePrivate
->localized_key
= CFSTR("bond");
878 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
880 interfacePrivate
->bond
.interfaces
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
881 // interfacePrivate->bond.mode = NULL;
882 // interfacePrivate->bond.options = NULL;
884 return interfacePrivate
;
889 SCNetworkInterfacePrivateRef
890 _SCBridgeInterfaceCreatePrivate(CFAllocatorRef allocator
,
891 CFStringRef bridge_if
)
893 SCNetworkInterfacePrivateRef interfacePrivate
;
895 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
);
896 if (interfacePrivate
== NULL
) {
900 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBridge
;
901 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
902 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, bridge_if
);
903 interfacePrivate
->builtin
= TRUE
;
904 interfacePrivate
->supportsVLAN
= __SCNetworkInterfaceSupportsVLAN(bridge_if
);
905 interfacePrivate
->sort_order
= kSortBridge
;
907 interfacePrivate
->localized_key
= CFSTR("bridge");
908 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
910 interfacePrivate
->bridge
.interfaces
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
911 // interfacePrivate->bridge.options = NULL;
913 return interfacePrivate
;
918 SCNetworkInterfacePrivateRef
919 _SCVLANInterfaceCreatePrivate(CFAllocatorRef allocator
,
922 SCNetworkInterfacePrivateRef interfacePrivate
;
924 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
);
925 if (interfacePrivate
== NULL
) {
929 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeVLAN
;
930 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
931 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, vlan_if
);
932 interfacePrivate
->builtin
= TRUE
;
933 interfacePrivate
->sort_order
= kSortVLAN
;
935 interfacePrivate
->localized_key
= CFSTR("vlan");
936 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
938 // interfacePrivate->vlan.interface = NULL;
939 // interfacePrivate->vlan.tag = NULL;
940 // interfacePrivate->vlan.options = NULL;
942 return interfacePrivate
;
947 #pragma mark Interface ordering
951 split_path(CFStringRef path
)
953 CFArrayRef components
;
954 CFMutableStringRef nPath
;
956 // turn '@'s into '/'s
957 nPath
= CFStringCreateMutableCopy(NULL
, 0, path
);
958 (void) CFStringFindAndReplace(nPath
,
961 CFRangeMake(0, CFStringGetLength(nPath
)),
964 // split path into components to be compared
965 components
= CFStringCreateArrayBySeparatingStrings(NULL
, nPath
, CFSTR("/"));
973 _SCNetworkInterfaceCompare(const void *val1
, const void *val2
, void *context
)
975 SCNetworkInterfacePrivateRef dev1
= (SCNetworkInterfacePrivateRef
)val1
;
976 SCNetworkInterfacePrivateRef dev2
= (SCNetworkInterfacePrivateRef
)val2
;
977 CFComparisonResult res
= kCFCompareEqualTo
;
979 /* sort by interface type */
980 if (dev1
->sort_order
!= dev2
->sort_order
) {
981 if (dev1
->sort_order
< dev2
->sort_order
) {
982 res
= kCFCompareLessThan
;
984 res
= kCFCompareGreaterThan
;
989 /* built-in interfaces sort first */
990 if (dev1
->builtin
!= dev2
->builtin
) {
992 res
= kCFCompareLessThan
;
994 res
= kCFCompareGreaterThan
;
999 /* ... and then, sort built-in interfaces by "location" */
1000 if (dev1
->builtin
) {
1001 if (dev1
->location
!= dev2
->location
) {
1002 if (isA_CFString(dev1
->location
)) {
1003 if (isA_CFString(dev2
->location
)) {
1004 res
= CFStringCompare(dev1
->location
, dev2
->location
, 0);
1006 res
= kCFCompareLessThan
;
1009 res
= kCFCompareGreaterThan
;
1012 if (res
!= kCFCompareEqualTo
) {
1018 /* ... and, then sort by IOPathMatch */
1019 if ((dev1
->path
!= NULL
) && (dev2
->path
!= NULL
)) {
1020 CFArrayRef elements1
;
1021 CFArrayRef elements2
;
1027 elements1
= split_path(dev1
->path
);
1028 n1
= CFArrayGetCount(elements1
);
1030 elements2
= split_path(dev2
->path
);
1031 n2
= CFArrayGetCount(elements2
);
1033 n
= (n1
<= n2
) ? n1
: n2
;
1034 for (i
= 0; i
< n
; i
++) {
1043 e1
= CFArrayGetValueAtIndex(elements1
, i
);
1044 e2
= CFArrayGetValueAtIndex(elements2
, i
);
1046 str
= _SC_cfstring_to_cstring(e1
, NULL
, 0, kCFStringEncodingUTF8
);
1048 q1
= strtoq(str
, &end
, 16);
1049 isNum
= ((*str
!= '\0') && (*end
== '\0') && (errno
== 0));
1050 CFAllocatorDeallocate(NULL
, str
);
1053 // if e1 is a valid numeric string
1054 str
= _SC_cfstring_to_cstring(e2
, NULL
, 0, kCFStringEncodingUTF8
);
1056 q2
= strtoq(str
, &end
, 16);
1057 isNum
= ((*str
!= '\0') && (*end
== '\0') && (errno
== 0));
1058 CFAllocatorDeallocate(NULL
, str
);
1061 // if e2 is also a valid numeric string
1064 res
= kCFCompareEqualTo
;
1066 } else if (q1
< q2
) {
1067 res
= kCFCompareLessThan
;
1069 res
= kCFCompareGreaterThan
;
1075 res
= CFStringCompare(e1
, e2
, 0);
1076 if (res
!= kCFCompareEqualTo
) {
1081 if (res
== kCFCompareEqualTo
) {
1083 res
= kCFCompareLessThan
;
1084 } else if (n1
< n2
) {
1085 res
= kCFCompareGreaterThan
;
1089 CFRelease(elements1
);
1090 CFRelease(elements2
);
1092 if (res
!= kCFCompareEqualTo
) {
1097 /* ... and, then sort by BSD interface name */
1098 if ((dev1
->entity_device
!= NULL
) && (dev2
->entity_device
!= NULL
)) {
1099 res
= CFStringCompare(dev1
->entity_device
, dev2
->entity_device
, 0);
1100 if (res
!= kCFCompareEqualTo
) {
1105 /* ... and lastly, sort by BSD interface unique identifier */
1106 if ((dev1
->entity_device_unique
!= NULL
) && (dev2
->entity_device_unique
!= NULL
)) {
1107 res
= CFStringCompare(dev1
->entity_device_unique
, dev2
->entity_device_unique
, 0);
1108 // if (res != kCFCompareEqualTo) {
1118 sort_interfaces(CFMutableArrayRef all_interfaces
)
1120 int n
= CFArrayGetCount(all_interfaces
);
1126 CFArraySortValues(all_interfaces
, CFRangeMake(0, n
), _SCNetworkInterfaceCompare
, NULL
);
1133 __SCNetworkInterfaceOrder(SCNetworkInterfaceRef interface
)
1135 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
1137 return interfacePrivate
->sort_order
;
1142 #pragma mark Interface details
1146 IOCopyCFStringValue(CFTypeRef ioVal
)
1148 if (isA_CFString(ioVal
)) {
1149 return CFStringCreateCopy(NULL
, ioVal
);
1152 if (isA_CFData(ioVal
)) {
1153 return CFStringCreateWithCString(NULL
,
1154 (const char *)CFDataGetBytePtr(ioVal
),
1155 kCFStringEncodingUTF8
);
1163 IODictionaryCopyCFStringValue(CFDictionaryRef io_dict
, CFStringRef io_key
)
1167 ioVal
= CFDictionaryGetValue(io_dict
, io_key
);
1168 return IOCopyCFStringValue(ioVal
);
1173 IOStringValueHasPrefix(CFTypeRef ioVal
, CFStringRef prefix
)
1175 Boolean match
= FALSE
;
1176 CFIndex prefixLen
= CFStringGetLength(prefix
);
1177 CFStringRef str
= NULL
;
1179 if (!isA_CFString(ioVal
)) {
1180 if (isA_CFData(ioVal
)) {
1181 str
= CFStringCreateWithCStringNoCopy(NULL
,
1182 (const char *)CFDataGetBytePtr(ioVal
),
1183 kCFStringEncodingUTF8
,
1191 if ((ioVal
!= NULL
) &&
1192 (CFStringGetLength(ioVal
) >= prefixLen
) &&
1193 (CFStringCompareWithOptions(ioVal
,
1195 CFRangeMake(0, prefixLen
),
1196 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
)) {
1200 if (str
!= NULL
) CFRelease(str
);
1205 static const struct {
1206 const CFStringRef name
;
1207 const CFStringRef slot
;
1208 } slot_mappings
[] = {
1210 { CFSTR("A1") , CFSTR("1") },
1211 { CFSTR("B1") , CFSTR("2") },
1212 { CFSTR("C1") , CFSTR("3") },
1214 // Blue&White G3, Yikes G4
1215 { CFSTR("J12"), CFSTR("1") },
1216 { CFSTR("J11"), CFSTR("2") },
1217 { CFSTR("J10"), CFSTR("3") },
1218 { CFSTR("J9"), CFSTR("4") },
1221 { CFSTR("A") , CFSTR("1") },
1222 { CFSTR("B") , CFSTR("2") },
1223 { CFSTR("C") , CFSTR("3") },
1224 { CFSTR("D") , CFSTR("4") },
1226 // Digital Audio G4 (and later models)
1227 { CFSTR("1") , CFSTR("1") },
1228 { CFSTR("2") , CFSTR("2") },
1229 { CFSTR("3") , CFSTR("3") },
1230 { CFSTR("4") , CFSTR("4") },
1231 { CFSTR("5") , CFSTR("5") }
1235 static const CFStringRef slot_prefixes
[] = {
1236 CFSTR("thunderbolt slot "),
1243 pci_slot(io_registry_entry_t interface
, CFTypeRef
*pci_slot_name
)
1246 io_registry_entry_t parent
;
1247 CFMutableStringRef slot
;
1248 CFTypeRef slot_name
;
1251 if (pci_slot_name
!= NULL
) *pci_slot_name
= NULL
;
1253 slot_name
= IORegistryEntryCreateCFProperty(interface
, CFSTR("AAPL,slot-name"), NULL
, 0);
1254 if (slot_name
!= NULL
) {
1257 slot
= CFStringCreateMutable(NULL
, 0);
1258 if (isA_CFString(slot_name
)) {
1259 if (pci_slot_name
!= NULL
) *pci_slot_name
= CFStringCreateCopy(NULL
, slot_name
);
1260 CFStringAppend(slot
, slot_name
);
1261 } else if (isA_CFData(slot_name
)) {
1262 if (pci_slot_name
!= NULL
) *pci_slot_name
= CFDataCreateCopy(NULL
, slot_name
);
1263 CFStringAppendCString(slot
,
1264 (const char *)CFDataGetBytePtr(slot_name
),
1265 kCFStringEncodingUTF8
);
1268 for (i
= 0; i
< sizeof(slot_prefixes
)/sizeof(slot_prefixes
[0]); i
++) {
1271 len
= CFStringGetLength(slot_prefixes
[i
]);
1272 if (CFStringGetLength(slot
) > len
) {
1273 (void) CFStringFindAndReplace(slot
,
1276 CFRangeMake(0, len
),
1277 kCFCompareCaseInsensitive
|kCFCompareAnchored
);
1281 for (i
= 0; i
< sizeof(slot_mappings
)/sizeof(slot_mappings
[0]); i
++) {
1282 if (CFStringCompare(slot
,
1283 slot_mappings
[i
].name
,
1284 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
1286 slot
= (CFMutableStringRef
)CFRetain(slot_mappings
[i
].slot
);
1291 CFRelease(slot_name
);
1294 kr
= IORegistryEntryGetParentEntry(interface
, kIOServicePlane
, &parent
);
1296 case kIOReturnSuccess
: {
1297 CFTypeRef parent_pci_slot_name
= NULL
;
1298 CFStringRef parent_slot
;
1300 parent_slot
= pci_slot(parent
, &parent_pci_slot_name
);
1301 if (parent_slot
!= NULL
) {
1302 if (slot
!= NULL
) CFRelease(slot
);
1303 slot
= (CFMutableStringRef
)parent_slot
;
1305 if (pci_slot_name
!= NULL
) {
1306 if (*pci_slot_name
!= NULL
) CFRelease(*pci_slot_name
);
1307 *pci_slot_name
= parent_pci_slot_name
;
1309 CFRelease(parent_pci_slot_name
);
1313 IOObjectRelease(parent
);
1316 case kIOReturnNoDevice
:
1317 // if we have hit the root node
1320 SCLog(TRUE
, LOG_DEBUG
, CFSTR("pci_slot IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr
);
1328 static CFComparisonResult
1329 compare_bsdNames(const void *val1
, const void *val2
, void *context
)
1331 CFStringRef bsd1
= (CFStringRef
)val1
;
1332 CFStringRef bsd2
= (CFStringRef
)val2
;
1334 return CFStringCompare(bsd1
, bsd2
, 0);
1339 pci_port(CFTypeRef slot_name
, int ift
, CFStringRef bsdName
)
1342 CFStringRef port_name
= NULL
;
1343 CFMutableArrayRef port_names
;
1346 CFStringRef match_keys
[2];
1347 CFTypeRef match_vals
[2];
1348 CFDictionaryRef match_dict
;
1349 CFDictionaryRef matching
;
1350 io_registry_entry_t slot
;
1351 io_iterator_t slot_iterator
= MACH_PORT_NULL
;
1353 match_keys
[0] = CFSTR("AAPL,slot-name");
1354 match_vals
[0] = slot_name
;
1356 match_dict
= CFDictionaryCreate(NULL
,
1357 (const void **)match_keys
,
1358 (const void **)match_vals
,
1360 &kCFTypeDictionaryKeyCallBacks
,
1361 &kCFTypeDictionaryValueCallBacks
);
1363 match_keys
[0] = CFSTR(kIOProviderClassKey
);
1364 match_vals
[0] = CFSTR("IOPCIDevice");
1366 match_keys
[1] = CFSTR(kIOPropertyMatchKey
);
1367 match_vals
[1] = match_dict
;
1369 // note: the "matching" dictionary will be consumed by the following
1370 matching
= CFDictionaryCreate(NULL
,
1371 (const void **)match_keys
,
1372 (const void **)match_vals
,
1373 sizeof(match_keys
)/sizeof(match_keys
[0]),
1374 &kCFTypeDictionaryKeyCallBacks
,
1375 &kCFTypeDictionaryValueCallBacks
);
1376 CFRelease(match_dict
);
1378 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &slot_iterator
);
1379 if (kr
!= kIOReturnSuccess
) {
1380 SCLog(TRUE
, LOG_DEBUG
, CFSTR("pci_port IOServiceGetMatchingServices() failed, kr = 0x%x"), kr
);
1381 return MACH_PORT_NULL
;
1384 port_names
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1386 while ((slot
= IOIteratorNext(slot_iterator
)) != MACH_PORT_NULL
) {
1387 io_registry_entry_t child
;
1388 io_iterator_t child_iterator
= MACH_PORT_NULL
;
1390 kr
= IORegistryEntryCreateIterator(slot
,
1392 kIORegistryIterateRecursively
,
1394 if (kr
!= kIOReturnSuccess
) {
1395 SCLog(TRUE
, LOG_DEBUG
, CFSTR("pci_port IORegistryEntryCreateIterator() failed, kr = 0x%x"), kr
);
1396 CFRelease(port_names
);
1397 return MACH_PORT_NULL
;
1400 while ((child
= IOIteratorNext(child_iterator
)) != MACH_PORT_NULL
) {
1401 if (IOObjectConformsTo(child
, kIONetworkInterfaceClass
)) {
1402 CFNumberRef child_if_type
;
1403 int child_ift
= ift
;
1405 child_if_type
= IORegistryEntryCreateCFProperty(child
,
1406 CFSTR(kIOInterfaceType
),
1409 if (child_if_type
!= NULL
) {
1410 if (!isA_CFNumber(child_if_type
) ||
1411 !CFNumberGetValue(child_if_type
, kCFNumberIntType
, &child_ift
)) {
1412 // assume that it's a match
1415 CFRelease(child_if_type
);
1418 if (ift
== child_ift
) {
1419 CFStringRef if_bsdName
;
1421 if_bsdName
= IORegistryEntryCreateCFProperty(child
,
1422 CFSTR(kIOBSDNameKey
),
1425 if (if_bsdName
!= NULL
) {
1426 CFArrayAppendValue(port_names
, if_bsdName
);
1427 CFRelease(if_bsdName
);
1431 IOObjectRelease(child
);
1433 IOObjectRelease(child_iterator
);
1434 IOObjectRelease(slot
);
1436 IOObjectRelease(slot_iterator
);
1438 n
= CFArrayGetCount(port_names
);
1440 CFArraySortValues(port_names
, CFRangeMake(0, n
), compare_bsdNames
, NULL
);
1441 n
= CFArrayGetFirstIndexOfValue(port_names
, CFRangeMake(0, n
), bsdName
);
1442 if (n
!= kCFNotFound
) {
1443 port_name
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%d"), n
+ 1);
1447 CFRelease(port_names
);
1453 pci_slot_info(io_registry_entry_t interface
, int ift
, CFStringRef
*slot_name
, CFStringRef
*port_name
)
1455 CFStringRef bsd_name
;
1457 CFTypeRef pci_slot_name
;
1462 bsd_name
= IORegistryEntryCreateCFProperty(interface
, CFSTR(kIOBSDNameKey
), NULL
, 0);
1463 if (bsd_name
== NULL
) {
1467 *slot_name
= pci_slot(interface
, &pci_slot_name
);
1468 if (*slot_name
!= NULL
) {
1469 if (pci_slot_name
!= NULL
) {
1470 *port_name
= pci_port(pci_slot_name
, ift
, bsd_name
);
1471 CFRelease(pci_slot_name
);
1476 CFRelease(bsd_name
);
1482 isBuiltin(io_registry_entry_t interface
)
1486 slot
= pci_slot(interface
, NULL
);
1488 // interfaces which have a "slot" are not built-in
1498 isBluetoothBuiltin(Boolean
*haveController
)
1500 Boolean builtin
= FALSE
;
1501 io_object_t hciController
;
1502 io_iterator_t iter
= MACH_PORT_NULL
;
1505 kr
= IOServiceGetMatchingServices(masterPort
,
1506 IOServiceMatching("IOBluetoothHCIController"),
1508 if ((kr
!= kIOReturnSuccess
) || (iter
== MACH_PORT_NULL
)) {
1509 if (kr
!= kIOReturnSuccess
) {
1510 SCLog(TRUE
, LOG_DEBUG
, CFSTR("isBluetoothBuiltin IOServiceGetMatchingServices() failed, kr = 0x%x"), kr
);
1512 *haveController
= FALSE
;
1515 *haveController
= TRUE
;
1517 hciController
= IOIteratorNext(iter
);
1518 IOObjectRelease(iter
);
1519 if(hciController
!= MACH_PORT_NULL
) {
1520 CFNumberRef idVendor
;
1522 idVendor
= IORegistryEntryCreateCFProperty(hciController
, CFSTR(kUSBVendorID
), NULL
, 0);
1523 if (idVendor
!= NULL
) {
1526 if (isA_CFNumber(idVendor
) &&
1527 CFNumberGetValue(idVendor
, kCFNumberIntType
, &idVendorVal
) &&
1528 (idVendorVal
== kIOUSBVendorIDAppleComputer
)) {
1532 CFRelease(idVendor
);
1535 IOObjectRelease(hciController
);
1543 isThunderbolt(io_registry_entry_t interface
)
1547 val
= IORegistryEntrySearchCFProperty(interface
,
1549 CFSTR(kPCIThunderboltString
),
1551 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1562 processUSBInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1563 io_registry_entry_t interface
,
1564 CFDictionaryRef interface_dict
,
1565 io_registry_entry_t controller
,
1566 CFDictionaryRef controller_dict
,
1567 io_registry_entry_t bus
,
1568 CFDictionaryRef bus_dict
)
1571 interfacePrivate
->usb
.name
= IORegistryEntrySearchCFProperty(interface
,
1573 CFSTR(kUSBProductString
),
1575 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1576 interfacePrivate
->usb
.vid
= IORegistryEntrySearchCFProperty(interface
,
1578 CFSTR(kUSBVendorID
),
1580 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1581 interfacePrivate
->usb
.pid
= IORegistryEntrySearchCFProperty(interface
,
1583 CFSTR(kUSBProductID
),
1585 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1592 update_interface_name(SCNetworkInterfacePrivateRef interfacePrivate
,
1593 io_registry_entry_t interface
,
1596 Boolean updated
= FALSE
;
1599 // check if a "Product Name" has been provided
1600 val
= IORegistryEntrySearchCFProperty(interface
,
1602 CFSTR(kIOPropertyProductNameKey
),
1604 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1605 if ((val
== NULL
) && useUSBInfo
&& (interfacePrivate
->usb
.name
!= NULL
)) {
1606 // else, use "USB Product Name" if available
1607 val
= CFRetain(interfacePrivate
->usb
.name
);
1610 CFStringRef productName
;
1612 productName
= IOCopyCFStringValue(val
);
1615 if (productName
!= NULL
) {
1616 if (CFStringGetLength(productName
) > 0) {
1617 // if we have a [somewhat reasonable?] product name
1618 if (interfacePrivate
->name
!= NULL
) {
1619 CFRelease(interfacePrivate
->name
);
1621 interfacePrivate
->name
= CFRetain(productName
);
1622 if (interfacePrivate
->localized_name
!= NULL
) {
1623 CFRelease(interfacePrivate
->localized_name
);
1625 interfacePrivate
->localized_name
= copy_interface_string(bundle
, productName
, TRUE
);
1630 CFRelease(productName
);
1639 #pragma mark Interface enumeration
1642 typedef Boolean (*processInterface
)(SCNetworkInterfacePrivateRef interfacePrivate
,
1643 io_registry_entry_t interface
,
1644 CFDictionaryRef interface_dict
,
1645 io_registry_entry_t controller
,
1646 CFDictionaryRef controller_dict
,
1647 io_registry_entry_t bus
,
1648 CFDictionaryRef bus_dict
);
1652 merge_override(SCNetworkInterfacePrivateRef interfacePrivate
,
1653 io_registry_entry_t interface
,
1654 CFStringRef override
)
1659 key
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("Device%@Overrides"), override
);
1660 val
= IORegistryEntrySearchCFProperty(interface
,
1664 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1667 if (isA_CFDictionary(val
)) {
1668 if (interfacePrivate
->overrides
== NULL
) {
1669 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
1671 &kCFTypeDictionaryKeyCallBacks
,
1672 &kCFTypeDictionaryValueCallBacks
);
1674 CFDictionarySetValue(interfacePrivate
->overrides
, override
, val
);
1684 processNetworkInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1685 io_registry_entry_t interface
,
1686 CFDictionaryRef interface_dict
,
1687 io_registry_entry_t controller
,
1688 CFDictionaryRef controller_dict
,
1689 io_registry_entry_t bus
,
1690 CFDictionaryRef bus_dict
)
1700 num
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceType
));
1701 if (isA_CFNumber(num
) &&
1702 CFNumberGetValue(num
, kCFNumberIntType
, &ift
)) {
1703 interfacePrivate
->type
= CFRetain(num
);
1705 SCLog(TRUE
, LOG_DEBUG
, CFSTR("processNetworkInterface() failed, no interface type"));
1713 if ((IOObjectConformsTo(controller
, "IO80211Controller")) ||
1714 (IOObjectConformsTo(controller
, "AirPortPCI" )) ||
1715 (IOObjectConformsTo(controller
, "AirPortDriver" ))) {
1716 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
1717 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1718 interfacePrivate
->sort_order
= kSortAirPort
;
1719 } else if (IOObjectConformsTo(controller
, "IOBluetoothBNEPDriver")) {
1720 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1721 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1722 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
1723 } else if (IOObjectConformsTo(controller
, "AppleUSBEthernetHost")) {
1724 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1725 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1726 interfacePrivate
->sort_order
= kSortTethered
;
1727 } else if (IOObjectConformsTo(controller
, "AppleUSBCDCECMData")) {
1728 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1729 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1730 interfacePrivate
->sort_order
= kSortWWANEthernet
;
1733 if (interfacePrivate
->interface_type
== NULL
) {
1734 val
= IORegistryEntrySearchCFProperty(interface
,
1736 CFSTR(kIOUserEthernetInterfaceRoleKey
),
1738 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1740 if (isA_CFString(val
)) {
1741 if (CFEqual(val
, CFSTR("Bluetooth PAN"))) {
1742 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1743 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1744 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
1745 } else if (CFEqual(val
, CFSTR("Bluetooth PAN-NAP"))) {
1746 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1747 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1748 interfacePrivate
->sort_order
= kSortBluetoothPAN_NAP
;
1749 } else if (CFEqual(val
, CFSTR("Bluetooth P2P"))) {
1750 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1751 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1752 interfacePrivate
->sort_order
= kSortBluetoothPAN_U
;
1760 if (interfacePrivate
->interface_type
== NULL
) {
1761 str
= IODictionaryCopyCFStringValue(bus_dict
, CFSTR("name"));
1763 if (CFEqual(str
, CFSTR("radio"))) {
1764 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
; // ??
1765 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1766 interfacePrivate
->sort_order
= kSortOtherWireless
;
1773 if (interfacePrivate
->interface_type
== NULL
) {
1774 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1775 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1776 interfacePrivate
->sort_order
= kSortEthernet
;
1778 // BOND support only enabled for ethernet devices
1779 interfacePrivate
->supportsBond
= TRUE
;
1782 // enable Bridge support
1783 interfacePrivate
->supportsBridge
= TRUE
;
1786 val
= isA_CFBoolean(CFDictionaryGetValue(interface_dict
, CFSTR(kIOBuiltin
)));
1788 val
= isA_CFBoolean(CFDictionaryGetValue(interface_dict
, CFSTR(kIOPrimaryInterface
)));
1791 interfacePrivate
->builtin
= CFBooleanGetValue(val
);
1793 interfacePrivate
->builtin
= isBuiltin(interface
);
1796 if (!interfacePrivate
->builtin
&&
1797 CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
)) {
1798 // always treat AirPort interfaces as built-in
1799 interfacePrivate
->builtin
= TRUE
;
1803 interfacePrivate
->location
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOLocation
));
1806 num
= CFDictionaryGetValue(controller_dict
, CFSTR(kIOFeatures
));
1807 if (isA_CFNumber(num
) &&
1808 CFNumberGetValue(num
, kCFNumberIntType
, & iVal
)) {
1809 if (iVal
& (kIONetworkFeatureHardwareVlan
| kIONetworkFeatureSoftwareVlan
)) {
1810 interfacePrivate
->supportsVLAN
= TRUE
;
1815 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
)) {
1816 interfacePrivate
->localized_key
= CFSTR("airport");
1817 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_GN
) {
1818 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-gn");
1819 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_NAP
) {
1820 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-nap");
1821 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_U
) {
1822 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-u");
1823 } else if (interfacePrivate
->sort_order
== kSortOtherWireless
) {
1824 interfacePrivate
->localized_key
= CFSTR("wireless");
1825 interfacePrivate
->localized_arg1
= CFRetain(CFSTR("")); // ??
1826 } else if (interfacePrivate
->builtin
) {
1827 if ((interfacePrivate
->location
== NULL
) ||
1828 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1829 interfacePrivate
->localized_key
= CFSTR("ether");
1831 interfacePrivate
->localized_key
= CFSTR("multiether");
1832 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->location
);
1835 CFStringRef provider
;
1837 // check provider class
1838 provider
= IORegistryEntrySearchCFProperty(interface
,
1840 CFSTR(kIOProviderClassKey
),
1842 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1843 if (provider
!= NULL
) {
1844 if (CFEqual(provider
, CFSTR("IOPCIDevice"))) {
1845 CFStringRef port_name
;
1846 CFStringRef slot_name
;
1848 // set interface "name"
1849 if (!update_interface_name(interfacePrivate
, interface
, FALSE
) &&
1850 pci_slot_info(interface
, ift
, &slot_name
, &port_name
)) {
1851 if (isThunderbolt(interface
)) {
1852 if (port_name
== NULL
) {
1853 interfacePrivate
->localized_key
= CFSTR("thunderbolt-ether");
1854 interfacePrivate
->localized_arg1
= slot_name
;
1856 interfacePrivate
->localized_key
= CFSTR("thunderbolt-multiether");
1857 interfacePrivate
->localized_arg1
= slot_name
;
1858 interfacePrivate
->localized_arg2
= port_name
;
1862 if (port_name
== NULL
) {
1863 interfacePrivate
->localized_key
= CFSTR("pci-ether");
1864 interfacePrivate
->localized_arg1
= slot_name
;
1866 interfacePrivate
->localized_key
= CFSTR("pci-multiether");
1867 interfacePrivate
->localized_arg1
= slot_name
;
1868 interfacePrivate
->localized_arg2
= port_name
;
1872 } else if (CFEqual(provider
, CFSTR("IOUSBDevice")) ||
1873 CFEqual(provider
, CFSTR("IOUSBInterface"))) {
1874 // get USB info (if available)
1875 processUSBInterface(interfacePrivate
,
1883 // set interface "name"
1884 if (!update_interface_name(interfacePrivate
, interface
, TRUE
)) {
1885 interfacePrivate
->localized_key
= CFSTR("usb-ether");
1886 interfacePrivate
->localized_arg1
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOBSDNameKey
));
1889 CFRelease(provider
);
1892 if (interfacePrivate
->localized_key
== NULL
) {
1893 // if no provider, not a PCI device, or no slot information
1894 interfacePrivate
->localized_key
= CFSTR("generic-ether");
1895 interfacePrivate
->localized_arg1
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOBSDNameKey
));
1902 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeFireWire
;
1905 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeFireWire
;
1908 interfacePrivate
->builtin
= isBuiltin(interface
);
1911 interfacePrivate
->sort_order
= kSortFireWire
;
1914 if (interfacePrivate
->builtin
) {
1915 interfacePrivate
->localized_key
= CFSTR("firewire");
1917 CFStringRef port_name
;
1918 CFStringRef slot_name
;
1920 // set interface "name"
1921 if (!update_interface_name(interfacePrivate
, interface
, FALSE
) &&
1922 pci_slot_info(interface
, ift
, &slot_name
, &port_name
)) {
1923 if (isThunderbolt(interface
)) {
1924 if (port_name
== NULL
) {
1925 interfacePrivate
->localized_key
= CFSTR("thunderbolt-firewire");
1926 interfacePrivate
->localized_arg1
= slot_name
;
1928 interfacePrivate
->localized_key
= CFSTR("thunderbolt-multifirewire");
1929 interfacePrivate
->localized_arg1
= slot_name
;
1930 interfacePrivate
->localized_arg2
= port_name
;
1933 if (port_name
== NULL
) {
1934 interfacePrivate
->localized_key
= CFSTR("pci-firewire");
1935 interfacePrivate
->localized_arg1
= slot_name
;
1937 interfacePrivate
->localized_key
= CFSTR("pci-multifirewire");
1938 interfacePrivate
->localized_arg1
= slot_name
;
1939 interfacePrivate
->localized_arg2
= port_name
;
1947 SCLog(TRUE
, LOG_DEBUG
, CFSTR("processNetworkInterface() failed, unknown interface type = %d"), ift
);
1952 interfacePrivate
->entity_device
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOBSDNameKey
));
1954 // Hardware (MAC) address
1955 data
= CFDictionaryGetValue(controller_dict
, CFSTR(kIOMACAddress
));
1956 if (isA_CFData(data
)) {
1957 interfacePrivate
->address
= CFRetain(data
);
1961 num
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceUnit
));
1962 if (isA_CFNumber(num
) &&
1963 CFNumberGetValue(num
, kCFNumberIntType
, & iVal
)) {
1964 interfacePrivate
->unit
= CFRetain(num
);
1967 // configuration [PPP] template override (now deprecated, use NetworkConfigurationOverrides)
1968 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypePPP
);
1975 set_connection_script(SCNetworkInterfacePrivateRef interfacePrivate
, CFStringRef script
)
1977 CFDictionaryRef dict
;
1978 CFMutableDictionaryRef newDict
;
1980 if (interfacePrivate
->overrides
== NULL
) {
1981 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
1983 &kCFTypeDictionaryKeyCallBacks
,
1984 &kCFTypeDictionaryValueCallBacks
);
1987 dict
= CFDictionaryGetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
1989 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
1991 newDict
= CFDictionaryCreateMutable(NULL
,
1993 &kCFTypeDictionaryKeyCallBacks
,
1994 &kCFTypeDictionaryValueCallBacks
);
1996 if (script
!= NULL
) {
1997 CFDictionarySetValue(newDict
, kSCPropNetModemConnectionScript
, script
);
1999 CFDictionaryRemoveValue(newDict
, kSCPropNetModemConnectionScript
);
2001 if (CFDictionaryGetCount(newDict
) > 0) {
2002 CFDictionarySetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
, newDict
);
2004 CFDictionaryRemoveValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
2008 if (CFDictionaryGetCount(interfacePrivate
->overrides
) == 0) {
2009 CFRelease(interfacePrivate
->overrides
);
2010 interfacePrivate
->overrides
= NULL
;
2017 is_valid_connection_script(CFStringRef script
)
2019 char ccl
[MAXPATHLEN
];
2020 char path
[MAXPATHLEN
];
2021 NSSearchPathEnumerationState state
;
2023 (void) _SC_cfstring_to_cstring(script
,
2026 kCFStringEncodingUTF8
);
2028 state
= NSStartSearchPathEnumeration(NSLibraryDirectory
,
2029 NSLocalDomainMask
|NSSystemDomainMask
);
2030 while ((state
= NSGetNextSearchPathEnumeration(state
, path
))) {
2032 struct stat statBuf
;
2034 if (ccl
[0] == '/') {
2035 path
[0] = '\0'; // if modemCCL is a full path
2037 strlcat(path
, "/Modem Scripts/", sizeof(path
));
2039 strlcat(path
, ccl
, sizeof(path
));
2041 if (stat(path
, &statBuf
) != 0) {
2042 if (errno
== ENOENT
) {
2046 SCLog(TRUE
, LOG_DEBUG
,
2047 CFSTR("processSerialInterface stat() failed: %s"),
2051 if (S_ISREG(statBuf
.st_mode
)) {
2052 // if we have a valid CCL script
2056 #define BUNDLE_EXT ".ccl"
2057 #define BUNDLE_EXT_LEN sizeof(BUNDLE_EXT) - 1
2062 if ((n
<= BUNDLE_EXT_LEN
) ||
2063 (strstr(&path
[n
- BUNDLE_EXT_LEN
], BUNDLE_EXT
) == NULL
)) {
2064 strlcat(path
, BUNDLE_EXT
, sizeof(path
));
2065 if (stat(path
, &statBuf
) != 0) {
2066 if (errno
== ENOENT
) {
2070 SCLog(TRUE
, LOG_DEBUG
,
2071 CFSTR("processSerialInterface stat() failed: %s"),
2076 if (S_ISDIR(statBuf
.st_mode
)) {
2077 // if we have a valid CCL bundle
2087 processSerialInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
2088 io_registry_entry_t interface
,
2089 CFDictionaryRef interface_dict
,
2090 io_registry_entry_t controller
,
2091 CFDictionaryRef controller_dict
,
2092 io_registry_entry_t bus
,
2093 CFDictionaryRef bus_dict
)
2095 CFStringRef base
= NULL
;
2097 Boolean isModem
= FALSE
;
2098 Boolean isWWAN
= FALSE
;
2099 CFStringRef modemCCL
= NULL
;
2104 val
= IORegistryEntrySearchCFProperty(interface
,
2106 kSCNetworkInterfaceHiddenPortKey
,
2108 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2111 return FALSE
; // if this interface should not be exposed
2114 // check if initializing
2115 val
= IORegistryEntrySearchCFProperty(interface
,
2117 kSCNetworkInterfaceInitializingKey
,
2119 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2121 Boolean initializing
;
2123 initializing
= isA_CFBoolean(val
) && CFBooleanGetValue(val
);
2126 return FALSE
; // if this interface is still initializing
2131 val
= IORegistryEntrySearchCFProperty(interface
,
2135 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2137 isWWAN
= isA_CFBoolean(val
) && CFBooleanGetValue(val
);
2142 interfacePrivate
->entity_device
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOTTYDeviceKey
));
2143 if (interfacePrivate
->entity_device
== NULL
) {
2147 base
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOTTYBaseNameKey
));
2149 base
= CFRetain(interfacePrivate
->entity_device
);
2155 * Exclude ports named "irda" because otherwise the IrDA ports on the
2156 * original iMac (rev's A through D) show up as serial ports. Given
2157 * that only the rev A actually had an IrDA port, and Mac OS X doesn't
2158 * even support it, these ports definitely shouldn't be listed.
2160 if (CFStringCompare(base
,
2162 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
2166 if (IOStringValueHasPrefix(base
, CFSTR("bluetooth"))) {
2167 Boolean haveController
= FALSE
;
2170 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBluetooth
;
2171 interfacePrivate
->sort_order
= kSortBluetooth
;
2172 interfacePrivate
->builtin
= isBluetoothBuiltin(&haveController
);
2173 if (!haveController
) {
2174 // if device with no controller present
2177 } else if (IOStringValueHasPrefix(base
, CFSTR("irda-ircomm"))) {
2179 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIrDA
;
2180 interfacePrivate
->sort_order
= kSortIrDA
;
2181 } else if (isWWAN
) {
2183 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeWWAN
;
2184 interfacePrivate
->sort_order
= kSortWWAN
;
2187 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeModem
;
2188 interfacePrivate
->sort_order
= kSortModem
;
2191 val
= IORegistryEntrySearchCFProperty(interface
,
2193 CFSTR(kIODeviceSupportsHoldKey
),
2195 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2199 if (isA_CFNumber(val
) &&
2200 CFNumberGetValue(val
, kCFNumberSInt32Type
, &v92
)) {
2201 interfacePrivate
->modemIsV92
= (v92
== 1);
2208 interfacePrivate
->entity_type
= kSCEntNetModem
;
2210 // Entity (Hardware)
2211 ift
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOSerialBSDTypeKey
));
2212 if (!isA_CFString(ift
)) {
2216 if (CFEqual(ift
, CFSTR(kIOSerialBSDModemType
))) {
2220 if (CFEqual(base
, CFSTR("modem"))) {
2221 interfacePrivate
->builtin
= TRUE
;
2222 interfacePrivate
->sort_order
= kSortInternalModem
;
2223 } else if (CFEqual(base
, CFSTR("usbmodem"))) {
2224 interfacePrivate
->sort_order
= kSortUSBModem
;
2226 } else if (CFEqual(ift
, CFSTR(kIOSerialBSDRS232Type
))) {
2228 interfacePrivate
->sort_order
= kSortSerialPort
;
2233 // configuration [PPP] template override (now deprecated, use NetworkConfigurationOverrides)
2234 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypePPP
);
2236 // configuration [Modem] template override (now deprecated, use NetworkConfigurationOverrides)
2237 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypeModem
);
2239 // look for modem CCL, unique identifier
2240 if (interfacePrivate
->overrides
!= NULL
) {
2241 val
= CFDictionaryGetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
2243 CFStringRef uniqueID
;
2245 modemCCL
= CFDictionaryGetValue(val
, kSCPropNetModemConnectionScript
);
2246 modemCCL
= isA_CFString(modemCCL
);
2248 uniqueID
= CFDictionaryGetValue(val
, CFSTR("UniqueIdentifier"));
2249 uniqueID
= isA_CFString(uniqueID
);
2250 if (uniqueID
!= NULL
) {
2251 // retain the device's base name and the unique id
2252 CFRelease(interfacePrivate
->entity_device
);
2253 interfacePrivate
->entity_device
= CFRetain(base
);
2254 interfacePrivate
->entity_device_unique
= CFStringCreateCopy(NULL
, uniqueID
);
2259 // if not part of the NetworkConfigurationOverrides/DeviceModemOverrides, look
2260 // a bit harder for the modem CCL
2261 if (modemCCL
== NULL
) {
2262 val
= IORegistryEntrySearchCFProperty(interface
,
2266 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2268 modemCCL
= IOCopyCFStringValue(val
);
2269 if (modemCCL
!= NULL
) {
2270 set_connection_script(interfacePrivate
, modemCCL
);
2271 CFRelease(modemCCL
);
2279 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIrDA
)) {
2280 interfacePrivate
->localized_key
= CFSTR("irda");
2281 } else if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBluetooth
)) {
2282 interfacePrivate
->localized_key
= CFSTR("bluetooth");
2284 CFStringRef localized
= NULL
;
2285 CFStringRef name
= NULL
;
2286 CFMutableStringRef port
;
2288 port
= CFStringCreateMutableCopy(NULL
, 0, base
);
2289 CFStringLowercase(port
, NULL
);
2292 CFStringAppend(port
, CFSTR("-port"));
2295 // set non-localized name
2296 if (bundle
!= NULL
) {
2297 name
= copy_interface_string(bundle
, port
, FALSE
);
2300 if (!CFEqual(port
, name
)) {
2301 // if [English] localization available
2302 interfacePrivate
->name
= name
;
2304 // if no [English] localization available, use TTY base name
2306 interfacePrivate
->name
= CFStringCreateCopy(NULL
, base
);
2309 interfacePrivate
->name
= CFStringCreateCopy(NULL
, base
);
2312 // set localized name
2313 if (bundle
!= NULL
) {
2314 localized
= copy_interface_string(bundle
, port
, TRUE
);
2316 if (localized
!= NULL
) {
2317 if (!CFEqual(port
, localized
)) {
2318 // if localization available
2319 interfacePrivate
->localized_name
= localized
;
2321 // if no localization available, use TTY base name
2322 CFRelease(localized
);
2323 interfacePrivate
->localized_name
= CFStringCreateCopy(NULL
, base
);
2326 interfacePrivate
->localized_name
= CFStringCreateCopy(NULL
, base
);
2329 if (!isModem
|| !CFEqual(base
, CFSTR("modem"))) {
2330 // get USB info (if available)
2331 processUSBInterface(interfacePrivate
,
2339 // set interface "name"
2340 if (update_interface_name(interfacePrivate
, interface
, TRUE
)) {
2341 // if "ModemCCL" not provided, also check if the product/interface
2342 // name matches a CCL script
2343 if ((modemCCL
== NULL
) &&
2344 is_valid_connection_script(interfacePrivate
->name
)) {
2345 set_connection_script(interfacePrivate
, interfacePrivate
->name
);
2357 if (!ok
&& (interfacePrivate
->entity_device
!= NULL
)) {
2358 CFRelease(interfacePrivate
->entity_device
);
2359 interfacePrivate
->entity_device
= NULL
;
2361 if (base
!= NULL
) CFRelease(base
);
2367 static SCNetworkInterfaceRef
2368 createInterface(io_registry_entry_t interface
, processInterface func
)
2370 io_registry_entry_t bus
= MACH_PORT_NULL
;
2371 CFMutableDictionaryRef bus_dict
= NULL
;
2372 io_registry_entry_t controller
= MACH_PORT_NULL
;
2373 CFMutableDictionaryRef controller_dict
= NULL
;
2374 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
2375 CFMutableDictionaryRef interface_dict
= NULL
;
2379 uint64_t entryID
= 0;
2381 kr
= IORegistryEntryGetPath(interface
, kIOServicePlane
, path
);
2382 if (kr
!= kIOReturnSuccess
) {
2383 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryGetPath() failed, kr = 0x%x"), kr
);
2387 kr
= IORegistryEntryCreateCFProperties(interface
, &interface_dict
, NULL
, kNilOptions
);
2388 if (kr
!= kIOReturnSuccess
) {
2389 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryCreateCFProperties() failed, kr = 0x%x"), kr
);
2393 /* get the controller node */
2394 kr
= IORegistryEntryGetParentEntry(interface
, kIOServicePlane
, &controller
);
2395 if (kr
!= KERN_SUCCESS
) {
2396 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr
);
2400 /* get the dictionary associated with the node */
2401 kr
= IORegistryEntryCreateCFProperties(controller
, &controller_dict
, NULL
, kNilOptions
);
2402 if (kr
!= KERN_SUCCESS
) {
2403 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryCreateCFProperties() failed, kr = 0x%x"), kr
);
2407 /* get the bus node */
2408 kr
= IORegistryEntryGetParentEntry(controller
, kIOServicePlane
, &bus
);
2409 if (kr
!= KERN_SUCCESS
) {
2410 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr
);
2414 /* get the dictionary associated with the node */
2415 kr
= IORegistryEntryCreateCFProperties(bus
, &bus_dict
, NULL
, kNilOptions
);
2416 if (kr
!= KERN_SUCCESS
) {
2417 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryCreateCFProperties() failed, kr = 0x%x"), kr
);
2421 /* get the registry entry ID */
2422 kr
= IORegistryEntryGetRegistryEntryID(interface
, &entryID
);
2423 if (kr
!= KERN_SUCCESS
) {
2424 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryGetRegistryEntryID() failed, kr = 0x%x"), kr
);
2428 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
);
2429 interfacePrivate
->path
= (path
!= NULL
) ? CFStringCreateWithCString(NULL
, path
, kCFStringEncodingUTF8
) : NULL
;
2430 interfacePrivate
->entryID
= entryID
;
2432 // configuration [PPP, Modem, DNS, IPv4, IPv6, Proxies, SMB] template overrides
2433 val
= IORegistryEntrySearchCFProperty(interface
,
2435 kSCNetworkInterfaceNetworkConfigurationOverridesKey
,
2437 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2439 if (isA_CFDictionary(val
)) {
2440 interfacePrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, val
);
2445 if ((*func
)(interfacePrivate
, interface
, interface_dict
, controller
, controller_dict
, bus
, bus_dict
)) {
2446 /* get user-notification / auto-configuration preference */
2447 val
= IORegistryEntrySearchCFProperty(interface
,
2449 kSCNetworkInterfaceConfigurationActionKey
,
2451 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2453 if (isA_CFString(val
)) {
2454 interfacePrivate
->configurationAction
= CFRetain(val
);
2459 /* get HiddenConfiguration preference */
2460 val
= IORegistryEntrySearchCFProperty(interface
,
2462 kSCNetworkInterfaceHiddenConfigurationKey
,
2464 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2466 interfacePrivate
->hidden
= TRUE
;
2470 CFRelease(interfacePrivate
);
2471 interfacePrivate
= NULL
;
2476 if (interface_dict
!= NULL
) CFRelease(interface_dict
);
2478 if (controller
!= MACH_PORT_NULL
) IOObjectRelease(controller
);
2479 if (controller_dict
!= NULL
) CFRelease(controller_dict
);
2481 if (bus
!= MACH_PORT_NULL
) IOObjectRelease(bus
);
2482 if (bus_dict
!= NULL
) CFRelease(bus_dict
);
2484 return (SCNetworkInterfaceRef
)interfacePrivate
;
2489 findMatchingInterfaces(CFDictionaryRef matching
, processInterface func
)
2491 CFMutableArrayRef interfaces
;
2492 io_registry_entry_t interface
;
2494 io_iterator_t iterator
= MACH_PORT_NULL
;
2497 * A reference to the "matching" dictionary will be consumed by the
2498 * the call to IOServiceGetMatchingServices so we bump up the retain
2503 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &iterator
);
2504 if (kr
!= kIOReturnSuccess
) {
2505 SCLog(TRUE
, LOG_DEBUG
, CFSTR("findMatchingInterfaces IOServiceGetMatchingServices() failed, kr = 0x%x"), kr
);
2509 interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2511 while ((interface
= IOIteratorNext(iterator
)) != MACH_PORT_NULL
) {
2512 SCNetworkInterfaceRef match
;
2514 match
= createInterface(interface
, func
);
2515 if (match
!= NULL
) {
2516 CFArrayAppendValue(interfaces
, match
);
2520 IOObjectRelease(interface
);
2523 IOObjectRelease(iterator
);
2530 #pragma mark helper functions
2534 findConfiguration(CFStringRef interface_type
)
2538 for (i
= 0; i
< sizeof(configurations
)/sizeof(configurations
[0]); i
++) {
2539 if (CFEqual(interface_type
, *configurations
[i
].interface_type
)) {
2550 __SCNetworkInterfaceGetDefaultConfigurationType(SCNetworkInterfaceRef interface
)
2552 CFIndex interfaceIndex
;
2553 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2555 if (interfacePrivate
->serviceID
== NULL
) {
2556 // if not associated with a service (yet)
2557 _SCErrorSet(kSCStatusInvalidArgument
);
2561 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2562 if (interfaceIndex
== kCFNotFound
) {
2563 // unknown interface type, use per-service configuration preferences
2564 return interfacePrivate
->interface_type
; // entity
2567 if (configurations
[interfaceIndex
].entity_hardware
!= NULL
) {
2568 // if configuration information can be associated with this interface type
2569 return *configurations
[interfaceIndex
].entity_hardware
;
2572 _SCErrorSet(kSCStatusInvalidArgument
);
2579 __SCNetworkInterfaceIsValidExtendedConfigurationType(SCNetworkInterfaceRef interface
,
2580 CFStringRef extendedType
,
2581 Boolean requirePerInterface
)
2583 CFStringRef defaultType
;
2584 CFIndex extendedIndex
;
2585 CFIndex interfaceIndex
;
2586 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2587 Boolean isL2TP
= FALSE
;
2590 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
2591 if (defaultType
== NULL
) {
2595 if (CFEqual(extendedType
, defaultType
)) {
2596 // extended and default configuration types cannot conflict
2600 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2601 if (interfaceIndex
== kCFNotFound
) {
2602 // configuration information for unknown interface type's
2603 // are stored along with the service and we don't allow
2604 // per-service extended configurations
2608 if (CFEqual(extendedType
, kSCEntNetIPSec
)) {
2609 CFStringRef interfaceType
;
2611 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
2612 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
2613 SCNetworkInterfaceRef child
;
2615 child
= SCNetworkInterfaceGetInterface(interface
);
2616 if (child
!= NULL
) {
2617 interfaceType
= SCNetworkInterfaceGetInterfaceType(child
);
2618 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
2625 if (requirePerInterface
&&
2626 !configurations
[interfaceIndex
].per_interface_config
&&
2628 // we don't allow per-service extended configurations (except
2629 // that we do allow IPSec as an extended type for PPP->L2TP)
2633 extendedIndex
= findConfiguration(extendedType
);
2634 if ((extendedIndex
!= kCFNotFound
) && !isL2TP
) {
2635 // extended type cannot match a known interface type (except
2636 // that we do allow IPSec as an extended type for PPP->L2TP)
2642 * Do we match specific/known extended configuration types (e.g. EAPOL)
2643 * and ensure that any non-standard extended configuration types be of
2644 * the form com.myCompany.myType?
2653 _SCErrorSet(kSCStatusInvalidArgument
);
2660 CFStringRef defaultType
;
2661 CFMutableArrayRef types
;
2662 } extendedConfiguration
, *extendedConfigurationRef
;
2666 __addExtendedConfigurationType(const void *key
, const void *value
, void *context
)
2668 CFStringRef extendedType
= (CFStringRef
)key
;
2669 extendedConfigurationRef myContextRef
= (extendedConfigurationRef
)context
;
2671 if (CFEqual(extendedType
, myContextRef
->defaultType
)) {
2672 // do not include the default configuration type
2676 if (CFArrayContainsValue(myContextRef
->types
,
2677 CFRangeMake(0, CFArrayGetCount(myContextRef
->types
)),
2679 // if extendedType already has already been added
2683 CFArrayAppendValue(myContextRef
->types
, extendedType
);
2690 extendedConfigurationTypes(SCNetworkInterfaceRef interface
)
2693 CFIndex interfaceIndex
;
2694 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2695 extendedConfiguration myContext
;
2696 SCNetworkServiceRef service
;
2700 myContext
.defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
2701 if (myContext
.defaultType
== NULL
) {
2702 myContext
.types
= NULL
;
2706 myContext
.types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2708 if (interfacePrivate
->serviceID
== NULL
) {
2709 // if not associated with a service (yet)
2713 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2714 if (interfaceIndex
== kCFNotFound
) {
2715 // we don't allow per-service extended configurations
2719 if (!configurations
[interfaceIndex
].per_interface_config
) {
2720 // known interface type but we still don't allow
2721 // per-service extended configurations
2725 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
2726 interfacePrivate
->prefs
,
2727 interfacePrivate
->serviceID
,
2730 sets
= SCNetworkSetCopyAll(interfacePrivate
->prefs
);
2731 n
= (sets
!= NULL
) ? CFArrayGetCount(sets
) : 0;
2733 for (i
= 0; i
< n
; i
++) {
2734 CFDictionaryRef configs
;
2737 CFArrayRef services
;
2738 SCNetworkSetRef set
;
2740 set
= CFArrayGetValueAtIndex(sets
, i
);
2741 services
= SCNetworkSetCopyServices(set
);
2742 found
= CFArrayContainsValue(services
,
2743 CFRangeMake(0, CFArrayGetCount(services
)),
2745 CFRelease(services
);
2751 // add stored extended configuration types
2752 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
2753 SCNetworkSetGetSetID(set
), // set
2754 interfacePrivate
->entity_device
, // service
2756 configs
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
2758 if (isA_CFDictionary(configs
)) {
2759 CFDictionaryApplyFunction(configs
,
2760 __addExtendedConfigurationType
,
2764 // add not-yet-stored extended configuration types
2765 if (interfacePrivate
->unsaved
!= NULL
) {
2766 CFDictionaryApplyFunction(interfacePrivate
->unsaved
,
2767 __addExtendedConfigurationType
,
2775 if (sets
!= NULL
) CFRelease(sets
);
2779 return myContext
.types
;
2784 copyConfigurationPaths(SCNetworkInterfacePrivateRef interfacePrivate
,
2785 CFStringRef extendedType
)
2787 CFMutableArrayRef array
;
2789 CFIndex interfaceIndex
;
2792 SCNetworkServiceRef service
;
2795 array
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2797 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2798 if (interfaceIndex
== kCFNotFound
) {
2799 // unknown interface type, use per-service configuration preferences
2800 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
2801 interfacePrivate
->serviceID
, // service
2802 extendedType
); // entity
2803 CFArrayAppendValue(array
, path
);
2808 if (!configurations
[interfaceIndex
].per_interface_config
) {
2809 // known interface type, per-service configuration preferences
2810 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
2811 interfacePrivate
->serviceID
, // service
2812 extendedType
); // entity
2813 CFArrayAppendValue(array
, path
);
2818 // known interface type, per-interface configuration preferences
2820 // 1. look for all sets which contain the associated service
2821 // 2. add a per-set path for the interface configuration for
2824 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
2825 interfacePrivate
->prefs
,
2826 interfacePrivate
->serviceID
,
2827 (SCNetworkInterfaceRef
)interfacePrivate
);
2829 sets
= SCNetworkSetCopyAll(interfacePrivate
->prefs
);
2830 n
= (sets
!= NULL
) ? CFArrayGetCount(sets
) : 0;
2832 for (i
= 0; i
< n
; i
++) {
2833 CFArrayRef services
;
2834 SCNetworkSetRef set
;
2836 set
= CFArrayGetValueAtIndex(sets
, i
);
2837 services
= SCNetworkSetCopyServices(set
);
2838 if (CFArrayContainsValue(services
,
2839 CFRangeMake(0, CFArrayGetCount(services
)),
2841 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
2842 SCNetworkSetGetSetID(set
), // set
2843 interfacePrivate
->entity_device
, // service
2844 extendedType
); // entity
2845 CFArrayAppendValue(array
, path
);
2848 CFRelease(services
);
2851 if (CFArrayGetCount(array
) == 0) {
2857 if (sets
!= NULL
) CFRelease(sets
);
2863 #pragma mark SCNetworkInterface <--> preferences entity
2868 __SCNetworkInterfaceCopyInterfaceEntity(SCNetworkInterfaceRef interface
)
2870 CFMutableDictionaryRef entity
;
2871 CFIndex interfaceIndex
;
2872 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2874 entity
= CFDictionaryCreateMutable(NULL
,
2876 &kCFTypeDictionaryKeyCallBacks
,
2877 &kCFTypeDictionaryValueCallBacks
);
2878 if (interfacePrivate
->entity_type
!= NULL
) {
2879 CFDictionarySetValue(entity
,
2880 kSCPropNetInterfaceType
,
2881 interfacePrivate
->entity_type
);
2883 if (interfacePrivate
->entity_subtype
!= NULL
) {
2884 CFDictionarySetValue(entity
,
2885 kSCPropNetInterfaceSubType
,
2886 interfacePrivate
->entity_subtype
);
2888 if (interfacePrivate
->entity_device
!= NULL
) {
2889 CFDictionarySetValue(entity
,
2890 kSCPropNetInterfaceDeviceName
,
2891 interfacePrivate
->entity_device
);
2893 if (interfacePrivate
->entity_device_unique
!= NULL
) {
2894 CFDictionarySetValue(entity
,
2895 CFSTR("DeviceUniqueIdentifier"),
2896 interfacePrivate
->entity_device_unique
);
2898 if (interfacePrivate
->hidden
) {
2899 CFDictionarySetValue(entity
,
2900 kSCNetworkInterfaceHiddenConfigurationKey
,
2904 // match the "hardware" with the lowest layer
2906 SCNetworkInterfaceRef nextInterface
;
2908 nextInterface
= SCNetworkInterfaceGetInterface(interface
);
2909 if (nextInterface
== NULL
) {
2913 interface
= nextInterface
;
2915 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2917 if (CFEqual(interface
, kSCNetworkInterfaceIPv4
)) {
2921 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2922 if (interfaceIndex
!= kCFNotFound
) {
2923 if (configurations
[interfaceIndex
].entity_hardware
!= NULL
) {
2924 CFDictionarySetValue(entity
,
2925 kSCPropNetInterfaceHardware
,
2926 *configurations
[interfaceIndex
].entity_hardware
);
2929 CFDictionarySetValue(entity
,
2930 kSCPropNetInterfaceHardware
,
2931 interfacePrivate
->interface_type
);
2934 // add the localized display name (which will only be used when/if the
2935 // interface is removed from the system)
2936 CFDictionarySetValue(entity
,
2937 kSCPropUserDefinedName
,
2938 SCNetworkInterfaceGetLocalizedDisplayName(interface
));
2940 // note that this is a V.92 capable modem
2941 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeModem
) &&
2942 interfacePrivate
->modemIsV92
) {
2946 num
= CFNumberCreate(NULL
, kCFNumberIntType
, &one
);
2947 CFDictionarySetValue(entity
,
2948 kSCPropNetInterfaceSupportsModemOnHold
,
2957 static SCNetworkInterfaceRef
2958 findInterface(CFArrayRef interfaces
, CFStringRef match_if
)
2963 n
= CFArrayGetCount(interfaces
);
2964 for (i
= 0; i
< n
; i
++) {
2965 SCNetworkInterfaceRef interface
= CFArrayGetValueAtIndex(interfaces
, i
);
2966 CFStringRef interfaceName
;
2968 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
2969 if ((interfaceName
!= NULL
) && CFEqual(interfaceName
, match_if
)) {
2970 CFRetain(interface
);
2978 static SCNetworkInterfaceRef
2979 findBondInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
2982 SCNetworkInterfaceRef interface
= NULL
;
2984 if (prefs
== NULL
) {
2988 // check if the interface is an Ethernet Bond
2989 bonds
= SCBondInterfaceCopyAll(prefs
);
2990 if (bonds
!= NULL
) {
2991 interface
= findInterface(bonds
, ifDevice
);
2997 static SCNetworkInterfaceRef
2998 findBridgeInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
3001 SCNetworkInterfaceRef interface
= NULL
;
3003 if (prefs
== NULL
) {
3007 // check if the interface is an bridge
3008 bridges
= SCBridgeInterfaceCopyAll(prefs
);
3009 if (bridges
!= NULL
) {
3010 interface
= findInterface(bridges
, ifDevice
);
3016 static SCNetworkInterfaceRef
3017 findVLANInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
3019 SCNetworkInterfaceRef interface
= NULL
;
3022 if (prefs
== NULL
) {
3026 // check if the interface is a VLAN
3027 vlans
= SCVLANInterfaceCopyAll(prefs
);
3028 if (vlans
!= NULL
) {
3029 interface
= findInterface(vlans
, ifDevice
);
3036 SCNetworkInterfaceRef
3037 _SCNetworkInterfaceCreateWithBSDName(CFAllocatorRef allocator
,
3038 CFStringRef bsdName
,
3041 CFMutableDictionaryRef entity
;
3042 SCNetworkInterfaceRef interface
;
3044 entity
= CFDictionaryCreateMutable(NULL
,
3046 &kCFTypeDictionaryKeyCallBacks
,
3047 &kCFTypeDictionaryValueCallBacks
);
3048 CFDictionarySetValue(entity
, kSCPropNetInterfaceDeviceName
, bsdName
);
3050 if ((flags
& kIncludeBondInterfaces
) == 0) {
3051 CFDictionarySetValue(entity
, CFSTR("_NO_BOND_INTERFACES_"), kCFBooleanTrue
);
3054 if ((flags
& kIncludeBridgeInterfaces
) == 0) {
3055 CFDictionarySetValue(entity
, CFSTR("_NO_BRIDGE_INTERFACES_"), kCFBooleanTrue
);
3058 if ((flags
& kIncludeVLANInterfaces
) == 0) {
3059 CFDictionarySetValue(entity
, CFSTR("_NO_VLAN_INTERFACES_"), kCFBooleanTrue
);
3062 interface
= _SCNetworkInterfaceCreateWithEntity(NULL
, entity
, NULL
);
3070 __SCNetworkInterfaceSetService(SCNetworkInterfaceRef interface
,
3071 SCNetworkServiceRef service
)
3073 SCNetworkInterfacePrivateRef interfacePrivate
;
3074 SCNetworkServicePrivateRef servicePrivate
;
3076 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3077 if (interfacePrivate
->prefs
!= NULL
) {
3078 CFRelease(interfacePrivate
->prefs
);
3079 interfacePrivate
->prefs
= NULL
;
3081 if (interfacePrivate
->serviceID
!= NULL
) {
3082 CFRelease(interfacePrivate
->serviceID
);
3083 interfacePrivate
->serviceID
= NULL
;
3086 servicePrivate
= (SCNetworkServicePrivateRef
)service
;
3087 if (servicePrivate
->prefs
!= NULL
) {
3088 interfacePrivate
->prefs
= CFRetain(servicePrivate
->prefs
);
3090 if (servicePrivate
->serviceID
!= NULL
) {
3091 interfacePrivate
->serviceID
= CFRetain(servicePrivate
->serviceID
);
3099 _SCNetworkInterfaceMatchesName(CFStringRef name
, CFStringRef key
)
3104 if (bundle
== NULL
) {
3109 if (!isA_CFString(name
)) {
3110 // if no interface "name"
3114 // check non-localized name for a match
3115 str
= copy_interface_string(bundle
, key
, FALSE
);
3117 match
= CFEqual(name
, str
);
3124 // check localized name for a match
3125 str
= copy_interface_string(bundle
, key
, TRUE
);
3127 match
= CFEqual(name
, str
);
3138 SCNetworkInterfaceRef
3139 _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef allocator
,
3140 CFDictionaryRef interface_entity
,
3141 SCNetworkServiceRef service
)
3143 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
3144 CFStringRef ifDevice
;
3145 CFStringRef ifName
= NULL
;
3146 CFStringRef ifSubType
;
3148 CFStringRef ifUnique
;
3149 CFArrayRef matching_interfaces
= NULL
;
3151 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
3152 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
3154 ifType
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceType
);
3155 if (ifType
== NULL
) {
3157 * The interface "Type" was not specified. We'll make an
3158 * assumption that this is an "Ethernet" interface. If a
3159 * real interface exists with the provided interface name
3160 * then the actual type will be set accordingly. If not, we'll
3161 * end up crafting an "Ethernet" SCNetworkInterface which
3162 * will keep the rest of the configuration APIs happy.
3164 ifType
= kSCValNetInterfaceTypeEthernet
;
3167 if (!isA_CFString(ifType
)) {
3171 ifSubType
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceSubType
);
3172 if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) ||
3173 CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
3174 if (!isA_CFString(ifSubType
)) {
3179 ifDevice
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceDeviceName
);
3180 ifUnique
= CFDictionaryGetValue(interface_entity
, CFSTR("DeviceUniqueIdentifier"));
3182 if (CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
) ||
3183 CFEqual(ifType
, kSCValNetInterfaceTypeFireWire
) ||
3184 (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) && CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPoE
))) {
3185 char bsdName
[IFNAMSIZ
];
3186 CFMutableDictionaryRef matching
;
3188 if (!isA_CFString(ifDevice
)) {
3192 if (CFEqual(ifDevice
, CFSTR("lo0"))) { // for _SCNetworkInterfaceCreateWithBSDName
3193 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
3197 if (_SC_cfstring_to_cstring(ifDevice
, bsdName
, sizeof(bsdName
), kCFStringEncodingASCII
) == NULL
) {
3201 matching
= IOBSDNameMatching(masterPort
, 0, bsdName
);
3202 if (matching
== NULL
) {
3205 matching_interfaces
= findMatchingInterfaces(matching
, processNetworkInterface
);
3206 CFRelease(matching
);
3207 } else if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
3208 if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPSerial
)) {
3209 CFDictionaryRef matching
;
3210 CFStringRef match_keys
[2];
3211 CFStringRef match_vals
[2];
3213 if (!isA_CFString(ifDevice
)) {
3217 match_keys
[0] = CFSTR(kIOProviderClassKey
);
3218 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
3220 match_keys
[1] = CFSTR(kIOTTYBaseNameKey
);
3221 match_vals
[1] = ifDevice
;
3223 matching
= CFDictionaryCreate(NULL
,
3224 (const void **)match_keys
,
3225 (const void **)match_vals
,
3226 sizeof(match_keys
)/sizeof(match_keys
[0]),
3227 &kCFTypeDictionaryKeyCallBacks
,
3228 &kCFTypeDictionaryValueCallBacks
);
3229 matching_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
);
3230 CFRelease(matching
);
3232 if (ifUnique
== NULL
) {
3234 Boolean useDeviceName
= TRUE
;
3236 n
= (matching_interfaces
!= NULL
) ? CFArrayGetCount(matching_interfaces
) : 0;
3240 for (i
= 0; i
< n
; i
++) {
3241 SCNetworkInterfacePrivateRef scanPrivate
;
3243 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
3244 if (scanPrivate
->entity_device_unique
!= NULL
) {
3245 useDeviceName
= FALSE
;
3251 if (useDeviceName
) {
3252 if (matching_interfaces
!= NULL
) {
3253 CFRelease(matching_interfaces
);
3256 match_keys
[1] = CFSTR(kIOTTYDeviceKey
);
3257 matching
= CFDictionaryCreate(NULL
,
3258 (const void **)match_keys
,
3259 (const void **)match_vals
,
3260 sizeof(match_keys
)/sizeof(match_keys
[0]),
3261 &kCFTypeDictionaryKeyCallBacks
,
3262 &kCFTypeDictionaryValueCallBacks
);
3263 matching_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
);
3264 CFRelease(matching
);
3267 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypeL2TP
)) {
3268 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
3269 kSCNetworkInterfaceTypeL2TP
);
3270 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPTP
)) {
3271 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
3272 kSCNetworkInterfaceTypePPTP
);
3274 // XXX do we allow non-Apple variants of PPP??? XXX
3275 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
3278 } else if (CFEqual(ifType
, kSCValNetInterfaceType6to4
)) {
3279 if (!isA_CFString(ifDevice
)) {
3283 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
3284 kSCNetworkInterfaceType6to4
);
3285 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeIPSec
)) {
3286 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
3287 kSCNetworkInterfaceTypeIPSec
);
3288 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeLoopback
)) {
3289 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
3290 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
3291 if (CFStringFind(ifSubType
, CFSTR("."), 0).location
!= kCFNotFound
) {
3292 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
3295 } else if ((CFStringFind(ifType
, CFSTR("."), 0).location
!= kCFNotFound
) && (ifDevice
== NULL
)) {
3296 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
3300 if (matching_interfaces
!= NULL
) {
3302 SCPreferencesRef prefs
;
3304 n
= CFArrayGetCount(matching_interfaces
);
3307 interfacePrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, 0);
3308 if (_SC_CFEqual(ifUnique
, interfacePrivate
->entity_device_unique
)) {
3309 // if the unique ID's match
3310 CFRetain(interfacePrivate
);
3314 interfacePrivate
= NULL
;
3317 if (!CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
)) {
3320 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), NULL
);
3321 if (prefs
== NULL
) {
3324 if (!CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_BOND_INTERFACES_"))) {
3325 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findBondInterface(prefs
, ifDevice
);
3328 if ((interfacePrivate
== NULL
)
3329 && !CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_BRIDGE_INTERFACES_"))) {
3330 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findBridgeInterface(prefs
, ifDevice
);
3333 if ((interfacePrivate
== NULL
)
3334 && !CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_VLAN_INTERFACES_"))) {
3335 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findVLANInterface(prefs
, ifDevice
);
3340 if (ifUnique
!= NULL
) {
3343 // we are looking for an interface with a unique ID
3344 // so let's try to focus our choices
3345 for (i
= 0; i
< n
; i
++) {
3346 SCNetworkInterfacePrivateRef scanPrivate
;
3348 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
3349 if (_SC_CFEqual(ifUnique
, scanPrivate
->entity_device_unique
)) {
3350 if (interfacePrivate
!= NULL
) {
3351 // if we've matched more than one interface
3352 interfacePrivate
= NULL
;
3355 interfacePrivate
= scanPrivate
;
3358 } else if (CFDictionaryGetValueIfPresent(interface_entity
,
3359 kSCPropUserDefinedName
,
3360 (const void **)&ifName
)) {
3363 // we don't have a unique ID but do have an interface
3364 // name. If the matching interfaces do have IDs than
3365 // we can try to focus our choices using the name
3366 for (i
= 0; i
< n
; i
++) {
3367 SCNetworkInterfacePrivateRef scanPrivate
;
3369 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
3370 if (scanPrivate
->entity_device_unique
!= NULL
) {
3371 SCNetworkInterfaceRef scan
= (SCNetworkInterfaceRef
)scanPrivate
;
3372 CFStringRef scanName
;
3374 scanName
= __SCNetworkInterfaceGetNonLocalizedDisplayName(scan
);
3375 if ((scanName
!= NULL
) && !_SC_CFEqual(ifName
, scanName
)) {
3376 continue; // if not the same display name
3380 if (interfacePrivate
!= NULL
) {
3381 // if we've matched more than one interface
3382 interfacePrivate
= NULL
;
3385 interfacePrivate
= scanPrivate
;
3388 if (interfacePrivate
== NULL
) {
3389 SCLog(TRUE
, LOG_ERR
, CFSTR("_SCNetworkInterfaceCreateWithEntity() failed, more than one interface matches %@"), ifDevice
);
3390 interfacePrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, 0);
3392 CFRetain(interfacePrivate
);
3395 CFRelease(matching_interfaces
);
3400 if (interfacePrivate
== NULL
) {
3402 * if device not present on this system
3404 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
);
3405 interfacePrivate
->entity_type
= ifType
;
3406 interfacePrivate
->entity_subtype
= ifSubType
;
3407 interfacePrivate
->entity_device
= (ifDevice
!= NULL
) ? CFStringCreateCopy(NULL
, ifDevice
) : NULL
;
3408 interfacePrivate
->entity_device_unique
= (ifUnique
!= NULL
) ? CFStringCreateCopy(NULL
, ifUnique
) : NULL
;
3410 if (CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
)) {
3411 CFStringRef entity_hardware
;
3413 entity_hardware
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceHardware
);
3414 if (isA_CFString((entity_hardware
)) &&
3415 CFEqual(entity_hardware
, kSCEntNetAirPort
)) {
3416 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
3417 interfacePrivate
->localized_key
= CFSTR("airport");
3418 interfacePrivate
->sort_order
= kSortAirPort
;
3422 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
3424 name
= CFDictionaryGetValue(interface_entity
, kSCPropUserDefinedName
);
3425 if (_SCNetworkInterfaceMatchesName(name
, CFSTR("iPhone"))) {
3426 interfacePrivate
->localized_key
= CFSTR("iPhone");
3427 interfacePrivate
->sort_order
= kSortTethered
;
3428 } else if (_SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-gn"))) {
3429 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-gn");
3430 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
3431 } else if (_SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-nap"))) {
3432 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-nap");
3433 interfacePrivate
->sort_order
= kSortBluetoothPAN_NAP
;
3434 } else if (_SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-u"))) {
3435 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-u");
3436 interfacePrivate
->sort_order
= kSortBluetoothPAN_U
;
3438 interfacePrivate
->sort_order
= kSortEthernet
;
3441 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeFireWire
)) {
3442 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeFireWire
;
3443 interfacePrivate
->sort_order
= kSortFireWire
;
3444 } else if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
3445 if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPoE
)) {
3446 CFStringRef entity_hardware
;
3448 entity_hardware
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceHardware
);
3449 if (isA_CFString((entity_hardware
)) &&
3450 CFEqual(entity_hardware
, kSCEntNetAirPort
)) {
3451 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
3452 interfacePrivate
->sort_order
= kSortAirPort
;
3454 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
3455 interfacePrivate
->sort_order
= kSortEthernet
;
3457 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPSerial
)) {
3458 if (CFStringHasPrefix(ifDevice
, CFSTR("Bluetooth"))) {
3459 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBluetooth
;
3460 interfacePrivate
->sort_order
= kSortBluetooth
;
3461 } else if (CFStringHasPrefix(ifDevice
, CFSTR("irda"))) {
3462 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIrDA
;
3463 interfacePrivate
->sort_order
= kSortIrDA
;
3464 } else if (CFStringHasPrefix(ifDevice
, CFSTR("wwan"))) {
3465 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeWWAN
;
3466 interfacePrivate
->sort_order
= kSortWWAN
;
3468 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeModem
;
3469 interfacePrivate
->sort_order
= kSortModem
;
3472 SCNetworkInterfaceRef child
;
3475 CFRelease(interfacePrivate
);
3476 child
= SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
, ifSubType
);
3477 interfacePrivate
= (SCNetworkInterfacePrivateRef
)child
;
3478 if (interfacePrivate
== NULL
) {
3482 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
3483 SCNetworkInterfaceRef child
;
3485 CFRelease(interfacePrivate
);
3486 child
= SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
, ifSubType
);
3487 interfacePrivate
= (SCNetworkInterfacePrivateRef
)child
;
3488 if (interfacePrivate
== NULL
) {
3491 } else if (CFStringFind(ifType
, CFSTR("."), 0).location
!= kCFNotFound
) {
3492 // if vendor interface
3493 if (vendor_interface_types
== NULL
) {
3494 vendor_interface_types
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
3496 CFSetAddValue(vendor_interface_types
, ifType
);
3498 interfacePrivate
->interface_type
= CFSetGetValue(vendor_interface_types
, ifType
);
3500 // if unknown interface
3501 CFRelease(interfacePrivate
);
3502 interfacePrivate
= NULL
;
3506 if (CFDictionaryContainsKey(interface_entity
, kSCNetworkInterfaceHiddenConfigurationKey
)) {
3507 interfacePrivate
->hidden
= TRUE
;
3511 if (service
!= NULL
) {
3512 __SCNetworkInterfaceSetService((SCNetworkInterfaceRef
)interfacePrivate
,
3515 // set prefs & serviceID to Bond member interfaces
3516 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBond
)) {
3521 members
= SCBondInterfaceGetMemberInterfaces((SCNetworkInterfaceRef
)interfacePrivate
);
3522 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
3523 for (i
= 0; i
< n
; i
++) {
3524 SCNetworkInterfaceRef member
;
3526 member
= CFArrayGetValueAtIndex(members
, i
);
3527 __SCNetworkInterfaceSetService(member
, service
);
3531 // set prefs & serviceID to Bridge member interfaces
3532 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBridge
)) {
3537 members
= SCBridgeInterfaceGetMemberInterfaces((SCNetworkInterfaceRef
)interfacePrivate
);
3538 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
3539 for (i
= 0; i
< n
; i
++) {
3540 SCNetworkInterfaceRef member
;
3542 member
= CFArrayGetValueAtIndex(members
, i
);
3543 __SCNetworkInterfaceSetService(member
, service
);
3547 // set prefs & serviceID to VLAN pyhsical interface
3548 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeVLAN
)) {
3549 SCNetworkInterfaceRef vlan_physical
;
3551 vlan_physical
= SCVLANInterfaceGetPhysicalInterface((SCNetworkInterfaceRef
)interfacePrivate
);
3552 if (vlan_physical
!= NULL
) {
3553 __SCNetworkInterfaceSetService(vlan_physical
, service
);
3558 if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
3559 SCNetworkInterfaceRef parent
;
3562 parent
= SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef
)interfacePrivate
,
3563 kSCNetworkInterfaceTypePPP
);
3564 CFRelease(interfacePrivate
);
3565 interfacePrivate
= (SCNetworkInterfacePrivateRef
)parent
;
3566 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
3567 SCNetworkInterfaceRef parent
;
3570 parent
= SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef
)interfacePrivate
,
3571 kSCNetworkInterfaceTypeVPN
);
3572 CFRelease(interfacePrivate
);
3573 interfacePrivate
= (SCNetworkInterfacePrivateRef
)parent
;
3576 return (SCNetworkInterfaceRef
)interfacePrivate
;
3581 #pragma mark SCNetworkInterface APIs
3586 __SCNetworkInterfaceCopyAll_IONetworkInterface(void)
3588 CFDictionaryRef matching
;
3589 CFArrayRef new_interfaces
;
3591 // get Ethernet, Firewire, and AirPort interfaces
3593 matching
= IOServiceMatching(kIONetworkInterfaceClass
);
3594 new_interfaces
= findMatchingInterfaces(matching
, processNetworkInterface
);
3595 CFRelease(matching
);
3597 return new_interfaces
;
3603 __SCNetworkInterfaceCopyAll_Modem()
3605 CFDictionaryRef matching
;
3606 CFStringRef match_keys
[2];
3607 CFStringRef match_vals
[2];
3608 CFArrayRef new_interfaces
;
3610 match_keys
[0] = CFSTR(kIOProviderClassKey
);
3611 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
3613 match_keys
[1] = CFSTR(kIOSerialBSDTypeKey
);
3614 match_vals
[1] = CFSTR(kIOSerialBSDModemType
);
3616 matching
= CFDictionaryCreate(NULL
,
3617 (const void **)match_keys
,
3618 (const void **)match_vals
,
3619 sizeof(match_keys
)/sizeof(match_keys
[0]),
3620 &kCFTypeDictionaryKeyCallBacks
,
3621 &kCFTypeDictionaryValueCallBacks
);
3622 new_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
);
3623 CFRelease(matching
);
3625 return new_interfaces
;
3631 __SCNetworkInterfaceCopyAll_RS232()
3633 CFDictionaryRef matching
;
3634 CFStringRef match_keys
[2];
3635 CFStringRef match_vals
[2];
3636 CFArrayRef new_interfaces
;
3638 match_keys
[0] = CFSTR(kIOProviderClassKey
);
3639 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
3641 match_keys
[1] = CFSTR(kIOSerialBSDTypeKey
);
3642 match_vals
[1] = CFSTR(kIOSerialBSDRS232Type
);
3644 matching
= CFDictionaryCreate(NULL
,
3645 (const void **)match_keys
,
3646 (const void **)match_vals
,
3647 sizeof(match_keys
)/sizeof(match_keys
[0]),
3648 &kCFTypeDictionaryKeyCallBacks
,
3649 &kCFTypeDictionaryValueCallBacks
);
3650 new_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
);
3651 CFRelease(matching
);
3653 return new_interfaces
;
3658 add_interfaces(CFMutableArrayRef all_interfaces
, CFArrayRef new_interfaces
)
3663 n
= CFArrayGetCount(new_interfaces
);
3664 for (i
= 0; i
< n
; i
++) {
3665 CFStringRef bsdName
;
3666 SCNetworkInterfaceRef interface
;
3668 interface
= CFArrayGetValueAtIndex(new_interfaces
, i
);
3669 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
3670 if (bsdName
!= NULL
) {
3671 CFArrayAppendValue(all_interfaces
, interface
);
3680 __waitForInterfaces()
3685 SCDynamicStoreRef store
;
3687 store
= SCDynamicStoreCreate(NULL
, CFSTR("SCNetworkInterfaceCopyAll"), NULL
, NULL
);
3688 if (store
== NULL
) {
3692 key
= SCDynamicStoreKeyCreate(NULL
, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin
);
3693 keys
= CFArrayCreate(NULL
, (const void **)&key
, 1, &kCFTypeArrayCallBacks
);
3694 ok
= SCDynamicStoreSetNotificationKeys(store
, keys
, NULL
);
3697 SCLog(TRUE
, LOG_ERR
,
3698 CFSTR("SCDynamicStoreSetNotificationKeys() failed: %s"), SCErrorString(SCError()));
3703 CFArrayRef changedKeys
;
3704 CFDictionaryRef dict
;
3705 Boolean quiet
= FALSE
;
3708 dict
= SCDynamicStoreCopyValue(store
, key
);
3710 if (isA_CFDictionary(dict
) &&
3711 (CFDictionaryContainsKey(dict
, CFSTR("*QUIET*")) ||
3712 CFDictionaryContainsKey(dict
, CFSTR("*TIMEOUT*")))) {
3721 ok
= SCDynamicStoreNotifyWait(store
);
3723 SCLog(TRUE
, LOG_ERR
,
3724 CFSTR("SCDynamicStoreNotifyWait() failed: %s"), SCErrorString(SCError()));
3728 changedKeys
= SCDynamicStoreCopyNotifiedKeys(store
);
3729 if (changedKeys
!= NULL
) {
3730 CFRelease(changedKeys
);
3742 CFArrayRef
/* of SCNetworkInterfaceRef's */
3743 _SCNetworkInterfaceCopyAllWithPreferences(SCPreferencesRef prefs
)
3745 CFMutableArrayRef all_interfaces
;
3746 CFArrayRef new_interfaces
;
3747 Boolean temp_preferences
= FALSE
;
3749 /* initialize runtime */
3750 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
3752 /* wait for IOKit to quiesce */
3753 pthread_once(&iokit_quiet
, __waitForInterfaces
);
3755 all_interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3757 // get Ethernet, Firewire, and AirPort interfaces
3758 new_interfaces
= __SCNetworkInterfaceCopyAll_IONetworkInterface();
3759 if (new_interfaces
!= NULL
) {
3760 add_interfaces(all_interfaces
, new_interfaces
);
3761 CFRelease(new_interfaces
);
3764 // get Modem interfaces
3765 new_interfaces
= __SCNetworkInterfaceCopyAll_Modem();
3766 if (new_interfaces
!= NULL
) {
3767 add_interfaces(all_interfaces
, new_interfaces
);
3768 CFRelease(new_interfaces
);
3771 // get serial (RS232) interfaces
3772 new_interfaces
= __SCNetworkInterfaceCopyAll_RS232();
3773 if (new_interfaces
!= NULL
) {
3774 add_interfaces(all_interfaces
, new_interfaces
);
3775 CFRelease(new_interfaces
);
3778 // get virtual network interfaces (Bond, Bridge, VLAN)
3779 if (prefs
== NULL
) {
3780 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterfaceCopyAll"), NULL
);
3781 if (prefs
!= NULL
) {
3782 temp_preferences
= TRUE
;
3785 if (prefs
!= NULL
) {
3786 new_interfaces
= SCBondInterfaceCopyAll(prefs
);
3787 if (new_interfaces
!= NULL
) {
3788 add_interfaces(all_interfaces
, new_interfaces
);
3789 CFRelease(new_interfaces
);
3792 new_interfaces
= SCBridgeInterfaceCopyAll(prefs
);
3793 if (new_interfaces
!= NULL
) {
3794 add_interfaces(all_interfaces
, new_interfaces
);
3795 CFRelease(new_interfaces
);
3798 new_interfaces
= SCVLANInterfaceCopyAll(prefs
);
3799 if (new_interfaces
!= NULL
) {
3800 add_interfaces(all_interfaces
, new_interfaces
);
3801 CFRelease(new_interfaces
);
3804 if (temp_preferences
) CFRelease(prefs
);
3807 // all interfaces have been identified, order and return
3808 sort_interfaces(all_interfaces
);
3810 return all_interfaces
;
3814 CFArrayRef
/* of SCNetworkInterfaceRef's */
3815 SCNetworkInterfaceCopyAll()
3817 CFArrayRef all_interfaces
;
3819 all_interfaces
= _SCNetworkInterfaceCopyAllWithPreferences(NULL
);
3820 return all_interfaces
;
3824 CFArrayRef
/* of kSCNetworkInterfaceTypeXXX CFStringRef's */
3825 SCNetworkInterfaceGetSupportedInterfaceTypes(SCNetworkInterfaceRef interface
)
3828 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3830 if (!isA_SCNetworkInterface(interface
)) {
3831 _SCErrorSet(kSCStatusInvalidArgument
);
3835 if (interfacePrivate
->supported_interface_types
!= NULL
) {
3839 i
= findConfiguration(interfacePrivate
->interface_type
);
3840 if (i
!= kCFNotFound
) {
3841 if (configurations
[i
].supported_interfaces
!= doNone
) {
3842 interfacePrivate
->supported_interface_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3843 if (configurations
[i
].supported_interfaces
& do6to4
) {
3844 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceType6to4
);
3846 if (configurations
[i
].supported_interfaces
& doL2TP
) {
3847 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeL2TP
);
3849 if (configurations
[i
].supported_interfaces
& doPPP
) {
3850 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypePPP
);
3852 if (configurations
[i
].supported_interfaces
& doPPTP
) {
3853 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypePPTP
);
3855 if (configurations
[i
].supported_interfaces
& doIPSec
) {
3856 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeIPSec
);
3860 SCNetworkInterfaceRef child
;
3862 child
= SCNetworkInterfaceGetInterface(interface
);
3863 if ((child
!= NULL
) && CFEqual(child
, kSCNetworkInterfaceIPv4
)) {
3864 interfacePrivate
->supported_interface_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3865 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeVPN
);
3871 return interfacePrivate
->supported_interface_types
;
3875 CFArrayRef
/* of kSCNetworkProtocolTypeXXX CFStringRef's */
3876 SCNetworkInterfaceGetSupportedProtocolTypes(SCNetworkInterfaceRef interface
)
3879 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3881 if (!isA_SCNetworkInterface(interface
)) {
3882 _SCErrorSet(kSCStatusInvalidArgument
);
3886 if (interfacePrivate
->supported_protocol_types
!= NULL
) {
3890 i
= findConfiguration(interfacePrivate
->interface_type
);
3891 if (i
!= kCFNotFound
) {
3892 if (configurations
[i
].supported_protocols
!= doNone
) {
3893 interfacePrivate
->supported_protocol_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3894 if (configurations
[i
].supported_protocols
& doDNS
) {
3895 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeDNS
);
3897 if (configurations
[i
].supported_protocols
& doIPv4
) {
3898 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeIPv4
);
3900 if (configurations
[i
].supported_protocols
& doIPv6
) {
3901 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeIPv6
);
3903 if (configurations
[i
].supported_protocols
& doProxies
) {
3904 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeProxies
);
3906 #if !TARGET_OS_IPHONE
3907 if (configurations
[i
].supported_protocols
& doSMB
) {
3908 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeSMB
);
3910 #endif // !TARGET_OS_IPHONE
3916 return interfacePrivate
->supported_protocol_types
;
3920 SCNetworkInterfaceRef
3921 SCNetworkInterfaceCreateWithInterface(SCNetworkInterfaceRef child
, CFStringRef interfaceType
)
3923 SCNetworkInterfacePrivateRef childPrivate
= (SCNetworkInterfacePrivateRef
)child
;
3925 SCNetworkInterfacePrivateRef parentPrivate
;
3927 if (!isA_SCNetworkInterface(child
)) {
3928 _SCErrorSet(kSCStatusInvalidArgument
);
3932 if (!isA_CFString(interfaceType
)) {
3933 _SCErrorSet(kSCStatusInvalidArgument
);
3937 if (CFEqual(child
, kSCNetworkInterfaceLoopback
)) {
3938 // can't layer on top of loopback
3939 _SCErrorSet(kSCStatusInvalidArgument
);
3943 childIndex
= findConfiguration(childPrivate
->interface_type
);
3945 parentPrivate
= __SCNetworkInterfaceCreatePrivate(NULL
,
3947 childPrivate
->prefs
,
3948 childPrivate
->serviceID
);
3949 if (parentPrivate
== NULL
) {
3950 _SCErrorSet(kSCStatusFailed
);
3954 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
3955 parentPrivate
->interface_type
= kSCNetworkInterfaceTypePPP
;
3956 parentPrivate
->entity_type
= kSCValNetInterfaceTypePPP
;
3959 if (childIndex
!= kCFNotFound
) {
3960 if (configurations
[childIndex
].ppp_subtype
!= NULL
) {
3961 parentPrivate
->entity_subtype
= *configurations
[childIndex
].ppp_subtype
;
3963 // sorry, the child interface does not support PPP
3967 // if the child's interface type not known, use the child entities "Type"
3968 parentPrivate
->entity_subtype
= childPrivate
->entity_type
;
3971 if (childPrivate
->entity_device
!= NULL
) {
3972 parentPrivate
->entity_device
= CFStringCreateCopy(NULL
, childPrivate
->entity_device
);
3975 if (childPrivate
->entity_device_unique
!= NULL
) {
3976 parentPrivate
->entity_device_unique
= CFStringCreateCopy(NULL
, childPrivate
->entity_device_unique
);
3978 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
3979 if ((childIndex
== kCFNotFound
) ||
3980 ((configurations
[childIndex
].supported_interfaces
& doL2TP
) != doL2TP
)) {
3981 // if the child interface does not support L2TP
3984 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeL2TP
;
3985 parentPrivate
->localized_key
= CFSTR("l2tp");
3986 parentPrivate
->entity_type
= kSCEntNetL2TP
; // interface config goes into "L2TP"
3987 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPTP
)) {
3988 if ((childIndex
== kCFNotFound
) ||
3989 ((configurations
[childIndex
].supported_interfaces
& doPPTP
) != doPPTP
)) {
3990 // if the child interface does not support PPTP
3993 parentPrivate
->interface_type
= kSCNetworkInterfaceTypePPTP
;
3994 parentPrivate
->localized_key
= CFSTR("pptp");
3995 parentPrivate
->entity_type
= kSCEntNetPPTP
; // interface config goes into "PPTP"
3996 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceType6to4
)) {
3997 if ((childIndex
== kCFNotFound
) ||
3998 ((configurations
[childIndex
].supported_interfaces
& do6to4
) != do6to4
)) {
3999 // if the child interface does not support 6to4
4003 parentPrivate
->interface_type
= kSCNetworkInterfaceType6to4
;
4004 parentPrivate
->localized_key
= CFSTR("6to4");
4005 parentPrivate
->entity_type
= kSCValNetInterfaceType6to4
;
4006 parentPrivate
->entity_device
= CFRetain(CFSTR("stf0"));
4007 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
4008 if ((childIndex
== kCFNotFound
) ||
4009 ((configurations
[childIndex
].supported_interfaces
& doIPSec
) != doIPSec
)) {
4010 // if the child interface does not support IPSec
4013 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeIPSec
;
4014 parentPrivate
->localized_key
= CFSTR("ipsec");
4015 parentPrivate
->entity_type
= kSCValNetInterfaceTypeIPSec
;
4016 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) {
4017 if (childIndex
!= kCFNotFound
) {
4018 // if not a "vendor" child interface
4022 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeVPN
;
4023 parentPrivate
->localized_key
= CFSTR("vpn");
4024 parentPrivate
->localized_arg1
= CFRetain(childPrivate
->entity_type
);
4025 parentPrivate
->entity_type
= kSCValNetInterfaceTypeVPN
;
4026 parentPrivate
->entity_subtype
= childPrivate
->entity_type
;
4027 if (childPrivate
->entity_device
!= NULL
) {
4028 parentPrivate
->entity_device
= CFStringCreateCopy(NULL
, childPrivate
->entity_device
);
4030 if (parentPrivate
->entity_subtype
!= NULL
) {
4031 CFArrayRef components
;
4033 CFStringRef vpnType
;
4036 // the "default" interface name is derived from the VPN type
4039 // com.apple.Apple-VPN.vpnplugin --> "Apple VPN"
4042 vpnType
= parentPrivate
->entity_subtype
;
4043 components
= CFStringCreateArrayBySeparatingStrings(NULL
, vpnType
, CFSTR("."));
4044 n
= CFArrayGetCount(components
);
4046 CFEqual(CFArrayGetValueAtIndex(components
, n
- 1), CFSTR("vpnplugin"))) {
4047 CFMutableStringRef str
;
4049 str
= CFStringCreateMutableCopy(NULL
,
4051 CFArrayGetValueAtIndex(components
, n
- 2));
4052 (void) CFStringFindAndReplace(str
,
4055 CFRangeMake(0, CFStringGetLength(str
)),
4057 parentPrivate
->localized_name
= str
;
4059 CFRelease(components
);
4061 } else if (CFStringFind(interfaceType
, CFSTR("."), 0).location
!= kCFNotFound
) {
4062 // if custom interface type
4063 if (vendor_interface_types
== NULL
) {
4064 vendor_interface_types
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
4066 CFSetAddValue(vendor_interface_types
, interfaceType
);
4068 parentPrivate
->interface_type
= CFSetGetValue(vendor_interface_types
, interfaceType
);
4069 parentPrivate
->entity_type
= parentPrivate
->interface_type
; // interface config goes into a
4070 // a dictionary with the same
4071 // name as the interfaceType
4073 // unknown interface type
4077 parentPrivate
->hidden
= childPrivate
->hidden
;
4079 if (childPrivate
->overrides
!= NULL
) {
4080 parentPrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, childPrivate
->overrides
);
4083 // The following change handles the case where a user has both an Ethernet and
4084 // PPPoE network service. Because a PPPoE service is typically associated with
4085 // an ISP we want it to be sorted higher in the service order.
4086 if ((parentPrivate
->entity_subtype
!= NULL
) &&
4087 (CFEqual(parentPrivate
->entity_subtype
, kSCValNetInterfaceSubTypePPPoE
))) {
4088 if ((childPrivate
->interface_type
!= NULL
) &&
4089 (CFEqual(childPrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
))) {
4090 parentPrivate
->sort_order
= kSortAirportPPP
;
4092 parentPrivate
->sort_order
= kSortEthernetPPP
;
4095 // set sort order of the parent to match the child interface
4096 parentPrivate
->sort_order
= childPrivate
->sort_order
;
4099 return (SCNetworkInterfaceRef
)parentPrivate
;
4103 CFRelease(parentPrivate
);
4104 _SCErrorSet(kSCStatusInvalidArgument
);
4111 __SCNetworkInterfaceGetDefaultConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
)
4113 CFDictionaryRef config
= NULL
;
4114 CFStringRef defaultType
;
4115 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4117 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
4118 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4120 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
4121 if (defaultType
!= NULL
) {
4125 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
4126 SCNetworkSetGetSetID(set
), // set
4127 interfacePrivate
->entity_device
, // interface
4128 defaultType
); // entity
4130 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
4133 if (config
== NULL
) {
4134 // if the "set" does not have a saved configuration, use
4135 // the [template] "interface" configuration
4136 if (interfacePrivate
->unsaved
!= NULL
) {
4137 config
= CFDictionaryGetValue(interfacePrivate
->unsaved
, defaultType
);
4138 if (config
== (CFDictionaryRef
)kCFNull
) {
4143 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
4154 static CFDictionaryRef
4155 __SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface
,
4156 CFStringRef extendedType
)
4158 CFDictionaryRef config
= NULL
;
4159 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4162 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
4163 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4165 paths
= copyConfigurationPaths(interfacePrivate
, extendedType
);
4166 if (paths
!= NULL
) {
4169 path
= CFArrayGetValueAtIndex(paths
, 0);
4170 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
4174 if (interfacePrivate
->unsaved
!= NULL
) {
4175 config
= CFDictionaryGetValue(interfacePrivate
->unsaved
, extendedType
);
4176 if (config
== (CFDictionaryRef
)kCFNull
) {
4182 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
4191 SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface
)
4193 CFDictionaryRef config
;
4194 CFStringRef defaultType
;
4196 if (!isA_SCNetworkInterface(interface
)) {
4197 _SCErrorSet(kSCStatusInvalidArgument
);
4201 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
4202 if (defaultType
== NULL
) {
4206 config
= __SCNetworkInterfaceGetConfiguration(interface
, defaultType
);
4207 if (config
== NULL
) {
4208 if (CFEqual(defaultType
, kSCEntNetAirPort
)) {
4209 SCNetworkInterfacePrivateRef interfacePrivate
;
4212 // if AirPort interface, check for a per-service config
4213 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4214 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
4215 interfacePrivate
->serviceID
, // service
4216 kSCEntNetAirPort
); // entity
4217 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
4221 if (config
== NULL
) {
4222 _SCErrorSet(kSCStatusOK
);
4230 SCNetworkInterfaceGetExtendedConfiguration(SCNetworkInterfaceRef interface
,
4231 CFStringRef extendedType
)
4233 CFDictionaryRef config
;
4235 if (!isA_SCNetworkInterface(interface
)) {
4236 _SCErrorSet(kSCStatusInvalidArgument
);
4240 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, TRUE
)) {
4241 _SCErrorSet(kSCStatusInvalidArgument
);
4245 config
= __SCNetworkInterfaceGetConfiguration(interface
, extendedType
);
4246 if (config
== NULL
) {
4247 _SCErrorSet(kSCStatusOK
);
4255 SCNetworkInterfaceGetBSDName(SCNetworkInterfaceRef interface
)
4257 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4259 if (!isA_SCNetworkInterface(interface
)) {
4260 _SCErrorSet(kSCStatusInvalidArgument
);
4264 if ((interfacePrivate
->interface
!= NULL
) &&
4265 (interfacePrivate
->interface
!= kSCNetworkInterfaceIPv4
)) {
4266 _SCErrorSet(kSCStatusOK
);
4270 return interfacePrivate
->entity_device
;
4275 SCNetworkInterfaceGetHardwareAddressString(SCNetworkInterfaceRef interface
)
4277 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4279 if (!isA_SCNetworkInterface(interface
)) {
4280 _SCErrorSet(kSCStatusInvalidArgument
);
4284 if ((interfacePrivate
->address
!= NULL
) &&
4285 (interfacePrivate
->addressString
== NULL
)) {
4289 char mac
[sizeof("xx:xx:xx:xx:xx:xx:xx:xx")];
4292 bp
= (uint8_t *)CFDataGetBytePtr(interfacePrivate
->address
);
4293 n
= CFDataGetLength(interfacePrivate
->address
) * 3;
4295 if (n
> sizeof(mac
)) {
4296 mac_p
= CFAllocatorAllocate(NULL
, 0, n
);
4299 for (cp
= mac_p
; n
> 0; n
-= 3) {
4300 cp
+= snprintf(cp
, n
, "%2.2x:", *bp
++);
4303 interfacePrivate
->addressString
= CFStringCreateWithCString(NULL
, mac_p
, kCFStringEncodingUTF8
);
4304 if (mac_p
!= mac
) CFAllocatorDeallocate(NULL
, mac_p
);
4307 return interfacePrivate
->addressString
;
4311 SCNetworkInterfaceRef
4312 SCNetworkInterfaceGetInterface(SCNetworkInterfaceRef interface
)
4314 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4316 if (!isA_SCNetworkInterface(interface
)) {
4317 _SCErrorSet(kSCStatusInvalidArgument
);
4321 return interfacePrivate
->interface
;
4326 SCNetworkInterfaceGetInterfaceType(SCNetworkInterfaceRef interface
)
4328 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4330 if (!isA_SCNetworkInterface(interface
)) {
4331 _SCErrorSet(kSCStatusInvalidArgument
);
4335 return interfacePrivate
->interface_type
;
4340 copy_interface_string(CFBundleRef bundle
, CFStringRef key
, Boolean localized
)
4342 CFStringRef str
= NULL
;
4345 str
= CFBundleCopyLocalizedString(bundle
,
4348 NETWORKINTERFACE_LOCALIZATIONS
);
4350 str
= _SC_CFBundleCopyNonLocalizedString(bundle
,
4353 NETWORKINTERFACE_LOCALIZATIONS
);
4361 copy_display_name(SCNetworkInterfaceRef interface
, Boolean localized
, Boolean oldLocalization
)
4363 CFMutableStringRef local
;
4366 local
= CFStringCreateMutable(NULL
, 0);
4368 while (interface
!= NULL
) {
4369 Boolean added
= FALSE
;
4370 SCNetworkInterfaceRef child
= NULL
;
4371 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4373 if ((interfacePrivate
->interface
!= NULL
) &&
4374 (interfacePrivate
->interface
!= kSCNetworkInterfaceIPv4
) &&
4375 !CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeVPN
)) {
4376 child
= interfacePrivate
->interface
;
4379 if ((bundle
!= NULL
) && (interfacePrivate
->localized_key
!= NULL
)) {
4381 CFStringRef key
= interfacePrivate
->localized_key
;
4383 if (oldLocalization
) {
4384 key
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("X-%@"),
4385 interfacePrivate
->localized_key
);
4387 fmt
= copy_interface_string(bundle
, key
, localized
);
4389 CFStringAppendFormat(local
,
4392 interfacePrivate
->localized_arg1
,
4393 interfacePrivate
->localized_arg2
);
4397 if (oldLocalization
) {
4403 (interfacePrivate
->prefs
!= NULL
) &&
4404 (interfacePrivate
->serviceID
!= NULL
) &&
4406 CFDictionaryRef entity
;
4409 // check for (and use) the name of the interface when it
4410 // was last available
4411 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,
4412 interfacePrivate
->serviceID
,
4413 kSCEntNetInterface
);
4414 entity
= SCPreferencesPathGetValue(interfacePrivate
->prefs
, path
);
4416 if (isA_CFDictionary(entity
)) {
4419 name
= CFDictionaryGetValue(entity
, kSCPropUserDefinedName
);
4420 if (isA_CFString(name
)) {
4421 CFStringAppend(local
, name
);
4428 // create (non-)localized name based on the interface type
4429 CFStringAppend(local
, interfacePrivate
->interface_type
);
4431 // ... and, if this is a leaf node, the interface device
4432 if ((interfacePrivate
->entity_device
!= NULL
) && (child
== NULL
)) {
4433 CFStringAppendFormat(local
, NULL
, CFSTR(" (%@)"), interfacePrivate
->entity_device
);
4437 if (child
!= NULL
) {
4438 // if this interface is layered over another
4439 CFStringAppend(local
, CFSTR(" --> "));
4445 name
= CFStringCreateCopy(NULL
, local
);
4452 #if !TARGET_OS_EMBEDDED && !TARGET_IPHONE_SIMULATOR
4455 __SCNetworkInterfaceCopyXLocalizedDisplayName(SCNetworkInterfaceRef interface
)
4459 if (!isA_SCNetworkInterface(interface
)) {
4460 _SCErrorSet(kSCStatusInvalidArgument
);
4464 name
= copy_display_name(interface
, TRUE
, TRUE
);
4471 __SCNetworkInterfaceCopyXNonLocalizedDisplayName(SCNetworkInterfaceRef interface
)
4473 CFStringRef localized_name
;
4475 if (!isA_SCNetworkInterface(interface
)) {
4476 _SCErrorSet(kSCStatusInvalidArgument
);
4480 localized_name
= copy_display_name(interface
, FALSE
, TRUE
);
4481 return localized_name
;
4483 #endif // !TARGET_OS_EMBEDDED && !TARGET_IPHONE_SIMULATOR
4488 __SCNetworkInterfaceGetNonLocalizedDisplayName(SCNetworkInterfaceRef interface
)
4490 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4492 if (!isA_SCNetworkInterface(interface
)) {
4493 _SCErrorSet(kSCStatusInvalidArgument
);
4497 if (interfacePrivate
->name
== NULL
) {
4498 interfacePrivate
->name
= copy_display_name(interface
, FALSE
, FALSE
);
4501 return interfacePrivate
->name
;
4506 SCNetworkInterfaceGetLocalizedDisplayName(SCNetworkInterfaceRef interface
)
4508 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4510 if (!isA_SCNetworkInterface(interface
)) {
4511 _SCErrorSet(kSCStatusInvalidArgument
);
4515 if (interfacePrivate
->localized_name
== NULL
) {
4516 interfacePrivate
->localized_name
= copy_display_name(interface
, TRUE
, FALSE
);
4519 return interfacePrivate
->localized_name
;
4525 __SCNetworkInterfaceGetTemplateOverrides(SCNetworkInterfaceRef interface
, CFStringRef overrideType
)
4527 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4528 CFDictionaryRef overrides
= NULL
;
4530 if (interfacePrivate
->overrides
!= NULL
) {
4531 overrides
= CFDictionaryGetValue(interfacePrivate
->overrides
, overrideType
);
4539 SCNetworkInterfaceGetTypeID(void)
4541 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
); /* initialize runtime */
4542 return __kSCNetworkInterfaceTypeID
;
4548 __SCNetworkInterfaceSetDefaultConfiguration(SCNetworkSetRef set
,
4549 SCNetworkInterfaceRef interface
,
4550 CFStringRef defaultType
,
4551 CFDictionaryRef config
,
4554 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4557 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
4558 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4560 if (defaultType
== NULL
) {
4561 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
4562 if (defaultType
== NULL
) {
4567 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
4574 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
4575 SCNetworkSetGetSetID(set
), // set
4576 interfacePrivate
->entity_device
, // interface
4577 defaultType
); // entity
4579 ok
= __setPrefsConfiguration(interfacePrivate
->prefs
, path
, config
, FALSE
);
4582 // if configuration has been saved
4583 if (interfacePrivate
->unsaved
!= NULL
) {
4584 CFDictionaryRemoveValue(interfacePrivate
->unsaved
, defaultType
);
4585 if (CFDictionaryGetCount(interfacePrivate
->unsaved
) == 0) {
4586 CFRelease(interfacePrivate
->unsaved
);
4587 interfacePrivate
->unsaved
= NULL
;
4593 if (config
== NULL
) {
4594 // remember that we are clearing the configuration
4595 config
= (CFDictionaryRef
)kCFNull
;
4598 if (interfacePrivate
->unsaved
== NULL
) {
4599 interfacePrivate
->unsaved
= CFDictionaryCreateMutable(NULL
,
4601 &kCFTypeDictionaryKeyCallBacks
,
4602 &kCFTypeDictionaryValueCallBacks
);
4604 CFDictionarySetValue(interfacePrivate
->unsaved
, defaultType
, config
);
4607 _SCErrorSet(kSCStatusNoKey
);
4618 __SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface
,
4619 CFStringRef extendedType
,
4620 CFDictionaryRef config
,
4623 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4627 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
4628 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4630 if (extendedType
== NULL
) {
4631 extendedType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
4632 if (extendedType
== NULL
) {
4637 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
4641 paths
= copyConfigurationPaths(interfacePrivate
, extendedType
);
4642 if (paths
!= NULL
) {
4646 n
= CFArrayGetCount(paths
);
4647 for (i
= 0; i
< n
; i
++) {
4650 path
= CFArrayGetValueAtIndex(paths
, i
);
4651 ok
= __setPrefsConfiguration(interfacePrivate
->prefs
, path
, config
, FALSE
);
4658 // if configuration has been saved
4659 if (interfacePrivate
->unsaved
!= NULL
) {
4660 CFDictionaryRemoveValue(interfacePrivate
->unsaved
, extendedType
);
4661 if (CFDictionaryGetCount(interfacePrivate
->unsaved
) == 0) {
4662 CFRelease(interfacePrivate
->unsaved
);
4663 interfacePrivate
->unsaved
= NULL
;
4671 if (config
== NULL
) {
4672 // remember that we are clearing the configuration
4673 config
= (CFDictionaryRef
)kCFNull
;
4676 if (interfacePrivate
->unsaved
== NULL
) {
4677 interfacePrivate
->unsaved
= CFDictionaryCreateMutable(NULL
,
4679 &kCFTypeDictionaryKeyCallBacks
,
4680 &kCFTypeDictionaryValueCallBacks
);
4682 CFDictionarySetValue(interfacePrivate
->unsaved
, extendedType
, config
);
4685 _SCErrorSet(kSCStatusNoKey
);
4694 SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface
, CFDictionaryRef config
)
4696 CFStringRef defaultType
;
4698 if (!isA_SCNetworkInterface(interface
)) {
4699 _SCErrorSet(kSCStatusInvalidArgument
);
4703 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
4704 if (defaultType
== NULL
) {
4708 return __SCNetworkInterfaceSetConfiguration(interface
, defaultType
, config
, FALSE
);
4713 SCNetworkInterfaceSetExtendedConfiguration(SCNetworkInterfaceRef interface
,
4714 CFStringRef extendedType
,
4715 CFDictionaryRef config
)
4717 if (!isA_SCNetworkInterface(interface
)) {
4718 _SCErrorSet(kSCStatusInvalidArgument
);
4722 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, TRUE
)) {
4726 return __SCNetworkInterfaceSetConfiguration(interface
, extendedType
, config
, FALSE
);
4731 #pragma mark SCNetworkInterface [Refresh Configuration] API
4734 #ifndef kSCEntNetRefreshConfiguration
4735 #define kSCEntNetRefreshConfiguration CFSTR("RefreshConfiguration")
4736 #endif // kSCEntNetRefreshConfiguration
4739 _SCNetworkInterfaceForceConfigurationRefresh(CFStringRef ifName
)
4743 SCDynamicStoreRef store
;
4745 if (!isA_CFString(ifName
)) {
4746 _SCErrorSet(kSCStatusInvalidArgument
);
4750 store
= SCDynamicStoreCreate(NULL
, CFSTR("_SCNetworkInterfaceForceConfigurationRefresh"), NULL
, NULL
);
4751 if (store
== NULL
) {
4755 key
= SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL
,
4756 kSCDynamicStoreDomainState
,
4758 kSCEntNetRefreshConfiguration
);
4759 ok
= SCDynamicStoreNotifyValue(store
, key
);
4767 __SCNetworkInterfaceForceConfigurationRefresh_helper(SCPreferencesRef prefs
, CFStringRef ifName
)
4769 CFDataRef data
= NULL
;
4771 SCPreferencesPrivateRef prefsPrivate
= (SCPreferencesPrivateRef
)prefs
;
4772 uint32_t status
= kSCStatusOK
;
4773 CFDataRef reply
= NULL
;
4775 if (prefsPrivate
->helper_port
== MACH_PORT_NULL
) {
4776 ok
= __SCPreferencesCreate_helper(prefs
);
4782 // serialize the interface name
4783 ok
= _SCSerializeString(ifName
, &data
, NULL
, NULL
);
4788 // have the helper "refresh" the configuration
4789 status
= kSCStatusOK
;
4791 ok
= _SCHelperExec(prefsPrivate
->helper_port
,
4792 SCHELPER_MSG_INTERFACE_REFRESH
,
4796 if (data
!= NULL
) CFRelease(data
);
4801 if (status
!= kSCStatusOK
) {
4810 if (prefsPrivate
->helper_port
!= MACH_PORT_NULL
) {
4811 _SCHelperClose(&prefsPrivate
->helper_port
);
4814 status
= kSCStatusAccessError
;
4819 _SCErrorSet(status
);
4825 SCNetworkInterfaceForceConfigurationRefresh(SCNetworkInterfaceRef interface
)
4828 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4830 if (!isA_SCNetworkInterface(interface
)) {
4831 _SCErrorSet(kSCStatusInvalidArgument
);
4835 ifName
= SCNetworkInterfaceGetBSDName(interface
);
4836 if (ifName
== NULL
) {
4837 _SCErrorSet(kSCStatusInvalidArgument
);
4841 if (interfacePrivate
->prefs
!= NULL
) {
4842 SCPreferencesRef prefs
= interfacePrivate
->prefs
;
4843 SCPreferencesPrivateRef prefsPrivate
= (SCPreferencesPrivateRef
)prefs
;
4845 if (prefsPrivate
->authorizationData
!= NULL
) {
4846 return __SCNetworkInterfaceForceConfigurationRefresh_helper(prefs
, ifName
);
4850 return _SCNetworkInterfaceForceConfigurationRefresh(ifName
);
4855 SCNetworkInterfaceRefreshConfiguration(CFStringRef ifName
)
4857 return _SCNetworkInterfaceForceConfigurationRefresh(ifName
);
4862 #pragma mark SCNetworkInterface Password APIs
4866 getPasswordID(CFDictionaryRef config
, CFStringRef serviceID
)
4868 CFStringRef unique_id
= NULL
;
4870 if (config
!= NULL
) {
4871 CFStringRef encryption
;
4873 encryption
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPasswordEncryption
);
4874 if (isA_CFString(encryption
) &&
4875 CFEqual(encryption
, kSCValNetPPPAuthPasswordEncryptionKeychain
)) {
4876 unique_id
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPassword
);
4879 if (unique_id
== NULL
) {
4880 unique_id
= serviceID
;
4888 copySharedSecretID(CFDictionaryRef config
, CFStringRef serviceID
)
4890 CFMutableStringRef shared_id
= NULL
;
4892 if (config
!= NULL
) {
4893 CFStringRef encryption
;
4895 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecretEncryption
);
4896 if (isA_CFString(encryption
) &&
4897 CFEqual(encryption
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) {
4898 shared_id
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecret
);
4899 if (shared_id
!= NULL
) {
4900 CFRetain(shared_id
);
4905 if (shared_id
== NULL
) {
4906 CFStringRef unique_id
;
4908 unique_id
= getPasswordID(config
, serviceID
);
4909 shared_id
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
4910 CFStringAppend(shared_id
, CFSTR(".SS"));
4918 copyXAuthID(CFDictionaryRef config
, CFStringRef serviceID
)
4920 CFMutableStringRef xauth_id
= NULL
;
4922 if (config
!= NULL
) {
4923 CFStringRef encryption
;
4925 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPasswordEncryption
);
4926 if (isA_CFString(encryption
) &&
4927 CFEqual(encryption
, kSCValNetIPSecXAuthPasswordEncryptionKeychain
)) {
4928 xauth_id
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPassword
);
4929 if (xauth_id
!= NULL
) {
4935 if (xauth_id
== NULL
) {
4936 CFStringRef unique_id
;
4938 unique_id
= getPasswordID(config
, serviceID
);
4939 xauth_id
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
4940 CFStringAppend(xauth_id
, CFSTR(".XAUTH"));
4948 checkInterfacePassword(SCNetworkInterfaceRef interface
,
4949 SCNetworkInterfacePasswordType passwordType
,
4950 SCPreferencesRef
*prefs
,
4951 CFStringRef
*serviceID
)
4953 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4955 if (!isA_SCNetworkInterface(interface
)) {
4959 *serviceID
= interfacePrivate
->serviceID
;
4960 if (*serviceID
== NULL
) {
4964 *prefs
= interfacePrivate
->prefs
;
4965 if (*prefs
== NULL
) {
4969 switch (passwordType
) {
4970 case kSCNetworkInterfacePasswordTypePPP
: {
4971 CFStringRef interfaceType
;
4973 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
4974 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
4982 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
4983 CFStringRef interfaceType
;
4985 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
4986 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
4987 interface
= SCNetworkInterfaceGetInterface(interface
);
4988 if (interface
!= NULL
) {
4989 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
4990 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
4991 // if PPP->L2TP interface
4995 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
4996 // if IPSec interface
5003 case kSCNetworkInterfacePasswordTypeEAPOL
: {
5007 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
5008 CFStringRef interfaceType
;
5010 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
5011 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
5012 // if IPSec interface
5019 case kSCNetworkInterfacePasswordTypeVPN
: {
5020 CFStringRef interfaceType
;
5022 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
5023 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) {
5039 _SCErrorSet(kSCStatusInvalidArgument
);
5045 SCNetworkInterfaceCheckPassword(SCNetworkInterfaceRef interface
,
5046 SCNetworkInterfacePasswordType passwordType
)
5048 Boolean exists
= FALSE
;
5049 SCPreferencesRef prefs
= NULL
;
5050 CFStringRef serviceID
= NULL
;
5052 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
5056 switch (passwordType
) {
5057 case kSCNetworkInterfacePasswordTypePPP
: {
5058 CFDictionaryRef config
;
5059 CFStringRef unique_id
;
5061 // get configuration
5062 config
= SCNetworkInterfaceGetConfiguration(interface
);
5065 unique_id
= getPasswordID(config
, serviceID
);
5068 exists
= __extract_password(prefs
,
5070 kSCPropNetPPPAuthPassword
,
5071 kSCPropNetPPPAuthPasswordEncryption
,
5072 kSCValNetPPPAuthPasswordEncryptionKeychain
,
5078 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
5079 CFDictionaryRef config
;
5081 CFStringRef shared_id
;
5083 // get configuration
5084 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
5086 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
5088 config
= SCNetworkInterfaceGetConfiguration(interface
);
5091 // get sharedSecret ID
5092 shared_id
= copySharedSecretID(config
, serviceID
);
5095 exists
= __extract_password(prefs
,
5097 kSCPropNetIPSecSharedSecret
,
5098 kSCPropNetIPSecSharedSecretEncryption
,
5099 kSCValNetIPSecSharedSecretEncryptionKeychain
,
5102 CFRelease(shared_id
);
5106 case kSCNetworkInterfacePasswordTypeEAPOL
: {
5107 CFDictionaryRef config
;
5108 CFStringRef unique_id
= NULL
;
5110 // get configuration
5111 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
5113 // get 802.1X identifier
5114 if (config
!= NULL
) {
5115 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
5117 if (!isA_CFString(unique_id
)) {
5122 exists
= _SCPreferencesSystemKeychainPasswordItemExists(prefs
, unique_id
);
5126 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
5127 CFDictionaryRef config
;
5128 CFStringRef xauth_id
;
5130 // get configuration
5131 config
= SCNetworkInterfaceGetConfiguration(interface
);
5134 xauth_id
= copyXAuthID(config
, serviceID
);
5137 exists
= __extract_password(prefs
,
5139 kSCPropNetIPSecXAuthPassword
,
5140 kSCPropNetIPSecXAuthPasswordEncryption
,
5141 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
5144 CFRelease(xauth_id
);
5148 case kSCNetworkInterfacePasswordTypeVPN
: {
5149 CFDictionaryRef config
;
5152 // get configuration
5153 config
= SCNetworkInterfaceGetConfiguration(interface
);
5156 vpn_id
= getPasswordID(config
, serviceID
);
5159 exists
= __extract_password(prefs
,
5161 kSCPropNetVPNAuthPassword
,
5162 kSCPropNetVPNAuthPasswordEncryption
,
5163 kSCValNetVPNAuthPasswordEncryptionKeychain
,
5170 _SCErrorSet(kSCStatusInvalidArgument
);
5179 SCNetworkInterfaceCopyPassword(SCNetworkInterfaceRef interface
,
5180 SCNetworkInterfacePasswordType passwordType
)
5182 CFDataRef password
= NULL
;
5183 SCPreferencesRef prefs
= NULL
;
5184 CFStringRef serviceID
= NULL
;
5186 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
5190 switch (passwordType
) {
5191 case kSCNetworkInterfacePasswordTypePPP
: {
5192 CFDictionaryRef config
;
5193 CFStringRef unique_id
;
5195 // get configuration
5196 config
= SCNetworkInterfaceGetConfiguration(interface
);
5199 unique_id
= getPasswordID(config
, serviceID
);
5202 (void) __extract_password(prefs
,
5204 kSCPropNetPPPAuthPassword
,
5205 kSCPropNetPPPAuthPasswordEncryption
,
5206 kSCValNetPPPAuthPasswordEncryptionKeychain
,
5212 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
5213 CFDictionaryRef config
;
5215 CFStringRef shared_id
;
5217 // get configuration
5218 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
5220 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
5222 config
= SCNetworkInterfaceGetConfiguration(interface
);
5225 // get sharedSecret ID
5226 shared_id
= copySharedSecretID(config
, serviceID
);
5229 (void) __extract_password(prefs
,
5231 kSCPropNetIPSecSharedSecret
,
5232 kSCPropNetIPSecSharedSecretEncryption
,
5233 kSCValNetIPSecSharedSecretEncryptionKeychain
,
5237 CFRelease(shared_id
);
5241 case kSCNetworkInterfacePasswordTypeEAPOL
: {
5242 CFDictionaryRef config
;
5243 CFStringRef unique_id
= NULL
;
5245 // get configuration
5246 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
5248 // get 802.1X identifier
5249 if (config
!= NULL
) {
5250 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
5252 if (!isA_CFString(unique_id
)) {
5253 _SCErrorSet(kSCStatusFailed
);
5258 password
= _SCPreferencesSystemKeychainPasswordItemCopy(prefs
, unique_id
);
5262 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
5263 CFDictionaryRef config
;
5264 CFStringRef xauth_id
;
5266 // get configuration
5267 config
= SCNetworkInterfaceGetConfiguration(interface
);
5270 xauth_id
= copyXAuthID(config
, serviceID
);
5273 (void) __extract_password(prefs
,
5275 kSCPropNetIPSecXAuthPassword
,
5276 kSCPropNetIPSecXAuthPasswordEncryption
,
5277 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
5280 CFRelease(xauth_id
);
5284 case kSCNetworkInterfacePasswordTypeVPN
: {
5285 CFDictionaryRef config
;
5288 // get configuration
5289 config
= SCNetworkInterfaceGetConfiguration(interface
);
5292 vpn_id
= getPasswordID(config
, serviceID
);
5295 (void) __extract_password(prefs
,
5297 kSCPropNetVPNAuthPassword
,
5298 kSCPropNetVPNAuthPasswordEncryption
,
5299 kSCValNetVPNAuthPasswordEncryptionKeychain
,
5306 _SCErrorSet(kSCStatusInvalidArgument
);
5315 SCNetworkInterfaceRemovePassword(SCNetworkInterfaceRef interface
,
5316 SCNetworkInterfacePasswordType passwordType
)
5319 SCPreferencesRef prefs
= NULL
;
5320 CFStringRef serviceID
= NULL
;
5322 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
5326 switch (passwordType
) {
5327 case kSCNetworkInterfacePasswordTypePPP
: {
5328 CFDictionaryRef config
;
5329 CFDictionaryRef newConfig
= NULL
;
5330 CFStringRef unique_id
;
5332 // get configuration
5333 config
= SCNetworkInterfaceGetConfiguration(interface
);
5336 unique_id
= getPasswordID(config
, serviceID
);
5339 ok
= __remove_password(prefs
,
5341 kSCPropNetPPPAuthPassword
,
5342 kSCPropNetPPPAuthPasswordEncryption
,
5343 kSCValNetPPPAuthPasswordEncryptionKeychain
,
5347 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
5348 if (newConfig
!= NULL
) CFRelease(newConfig
);
5354 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
5355 CFDictionaryRef config
;
5357 CFDictionaryRef newConfig
= NULL
;
5358 CFStringRef shared_id
;
5360 // get configuration
5361 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
5363 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
5365 config
= SCNetworkInterfaceGetConfiguration(interface
);
5368 // get sharedSecret ID
5369 shared_id
= copySharedSecretID(config
, serviceID
);
5372 ok
= __remove_password(prefs
,
5374 kSCPropNetIPSecSharedSecret
,
5375 kSCPropNetIPSecSharedSecretEncryption
,
5376 kSCValNetIPSecSharedSecretEncryptionKeychain
,
5381 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
5385 ok
= SCNetworkInterfaceSetConfiguration(interface
,
5388 if (newConfig
!= NULL
) CFRelease(newConfig
);
5391 CFRelease(shared_id
);
5395 case kSCNetworkInterfacePasswordTypeEAPOL
: {
5396 CFDictionaryRef config
;
5397 CFStringRef unique_id
= NULL
;
5399 // get configuration
5400 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
5402 // get 802.1X identifier
5403 if (config
!= NULL
) {
5404 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
5406 if (!isA_CFString(unique_id
)) {
5407 _SCErrorSet(kSCStatusFailed
);
5412 ok
= _SCPreferencesSystemKeychainPasswordItemRemove(prefs
, unique_id
);
5416 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
5417 CFDictionaryRef config
;
5418 CFDictionaryRef newConfig
= NULL
;
5419 CFStringRef xauth_id
;
5421 // get configuration
5422 config
= SCNetworkInterfaceGetConfiguration(interface
);
5425 xauth_id
= copyXAuthID(config
, serviceID
);
5428 ok
= __remove_password(prefs
,
5430 kSCPropNetIPSecXAuthPassword
,
5431 kSCPropNetIPSecXAuthPasswordEncryption
,
5432 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
5436 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
5437 if (newConfig
!= NULL
) CFRelease(newConfig
);
5440 CFRelease(xauth_id
);
5444 case kSCNetworkInterfacePasswordTypeVPN
: {
5445 CFDictionaryRef config
;
5446 CFDictionaryRef newConfig
= NULL
;
5449 // get configuration
5450 config
= SCNetworkInterfaceGetConfiguration(interface
);
5453 vpn_id
= getPasswordID(config
, serviceID
);
5456 ok
= __remove_password(prefs
,
5458 kSCPropNetVPNAuthPassword
,
5459 kSCPropNetVPNAuthPasswordEncryption
,
5460 kSCValNetVPNAuthPasswordEncryptionKeychain
,
5464 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
5465 if (newConfig
!= NULL
) CFRelease(newConfig
);
5471 _SCErrorSet(kSCStatusInvalidArgument
);
5480 SCNetworkInterfaceSetPassword(SCNetworkInterfaceRef interface
,
5481 SCNetworkInterfacePasswordType passwordType
,
5483 CFDictionaryRef options
)
5485 CFStringRef account
= NULL
;
5486 CFDictionaryRef config
;
5487 CFStringRef description
= NULL
;
5488 CFStringRef label
= NULL
;
5490 SCPreferencesRef prefs
= NULL
;
5491 CFStringRef serviceID
= NULL
;
5493 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
5497 switch (passwordType
) {
5498 case kSCNetworkInterfacePasswordTypePPP
: {
5499 SCNetworkServiceRef service
= NULL
;
5500 CFStringRef unique_id
;
5502 // get configuration
5503 config
= SCNetworkInterfaceGetConfiguration(interface
);
5506 unique_id
= getPasswordID(config
, serviceID
);
5508 // get "Account", "Name", "Kind"
5509 if (config
!= NULL
) {
5510 // auth name --> keychain "Account"
5511 account
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthName
);
5513 // PPP [user defined] "name" --> keychain "Name"
5514 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
5517 if (label
== NULL
) {
5518 // service name --> keychain "Name"
5519 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
5524 label
= SCNetworkServiceGetName(service
);
5525 if (label
== NULL
) {
5526 // interface name --> keychain "Name"
5527 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
5531 if (bundle
!= NULL
) {
5532 // "PPP Password" --> keychain "Kind"
5533 description
= CFBundleCopyLocalizedString(bundle
,
5534 CFSTR("KEYCHAIN_KIND_PPP_PASSWORD"),
5535 CFSTR("PPP Password"),
5540 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
5542 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
5543 (description
!= NULL
) ? description
: CFSTR("PPP Password"),
5548 CFMutableDictionaryRef newConfig
;
5550 if (config
!= NULL
) {
5551 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
5553 newConfig
= CFDictionaryCreateMutable(NULL
,
5555 &kCFTypeDictionaryKeyCallBacks
,
5556 &kCFTypeDictionaryValueCallBacks
);
5558 CFDictionarySetValue(newConfig
,
5559 kSCPropNetPPPAuthPassword
,
5561 CFDictionarySetValue(newConfig
,
5562 kSCPropNetPPPAuthPasswordEncryption
,
5563 kSCValNetPPPAuthPasswordEncryptionKeychain
);
5564 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
5565 CFRelease(newConfig
);
5568 if (description
!= NULL
) CFRelease(description
);
5569 if (service
!= NULL
) CFRelease(service
);
5573 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
5574 CFDictionaryRef baseConfig
= NULL
;
5576 SCNetworkServiceRef service
= NULL
;
5577 CFStringRef shared_id
;
5579 // get configuration
5580 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
5581 config
= SCNetworkInterfaceGetConfiguration(interface
);
5583 baseConfig
= config
;
5584 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
5587 // get sharedSecret ID
5588 shared_id
= copySharedSecretID(config
, serviceID
);
5590 // get "Account", "Name", "Kind"
5591 if (config
!= NULL
) {
5592 CFStringRef localIdentifier
;
5593 CFStringRef localIdentifierType
;
5595 if (CFDictionaryGetValueIfPresent(config
,
5596 kSCPropNetIPSecLocalIdentifierType
,
5597 (const void **)&localIdentifierType
)
5598 && CFEqual(localIdentifierType
, kSCValNetIPSecLocalIdentifierTypeKeyID
)
5599 && CFDictionaryGetValueIfPresent(config
,
5600 kSCPropNetIPSecLocalIdentifier
,
5601 (const void **)&localIdentifier
)
5602 && isA_CFString(localIdentifier
)) {
5603 // local identifier --> keychain "Account"
5604 account
= localIdentifier
;
5607 // PPP [user defined] "name" --> keychain "Name"
5609 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
5611 if (baseConfig
!= NULL
) {
5612 label
= CFDictionaryGetValue(baseConfig
, kSCPropUserDefinedName
);
5617 if (label
== NULL
) {
5618 // service name --> keychain "Name"
5619 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
5624 label
= SCNetworkServiceGetName(service
);
5625 if (label
== NULL
) {
5626 // interface name --> keychain "Name"
5627 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
5631 if (bundle
!= NULL
) {
5632 // "IPSec Shared Secret" --> keychain "Kind"
5633 description
= CFBundleCopyLocalizedString(bundle
,
5634 CFSTR("KEYCHAIN_KIND_IPSEC_SHARED_SECRET"),
5635 CFSTR("IPSec Shared Secret"),
5640 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
5642 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
5643 (description
!= NULL
) ? description
: CFSTR("IPSec Shared Secret"),
5648 CFMutableDictionaryRef newConfig
= NULL
;
5650 if (config
!= NULL
) {
5651 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
5653 newConfig
= CFDictionaryCreateMutable(NULL
,
5655 &kCFTypeDictionaryKeyCallBacks
,
5656 &kCFTypeDictionaryValueCallBacks
);
5658 CFDictionarySetValue(newConfig
,
5659 kSCPropNetIPSecSharedSecret
,
5661 CFDictionarySetValue(newConfig
,
5662 kSCPropNetIPSecSharedSecretEncryption
,
5663 kSCValNetIPSecSharedSecretEncryptionKeychain
);
5665 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
5669 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
5671 CFRelease(newConfig
);
5674 if (description
!= NULL
) CFRelease(description
);
5675 if (service
!= NULL
) CFRelease(service
);
5676 CFRelease(shared_id
);
5680 case kSCNetworkInterfacePasswordTypeEAPOL
: {
5681 CFStringRef account
= NULL
;
5682 CFStringRef unique_id
= NULL
;
5684 // get configuration
5685 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
5687 // get 802.1X identifier
5688 if (config
!= NULL
) {
5689 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
5690 unique_id
= isA_CFString(unique_id
);
5692 if (unique_id
!= NULL
) {
5693 CFRetain(unique_id
);
5697 uuid
= CFUUIDCreate(NULL
);
5698 unique_id
= CFUUIDCreateString(NULL
, uuid
);
5702 // 802.1x UserName --> keychain "Account"
5703 if (config
!= NULL
) {
5704 account
= CFDictionaryGetValue(config
, kEAPClientPropUserName
);
5707 // get "Name", "Kind"
5708 if (bundle
!= NULL
) {
5709 CFStringRef interface_name
;
5711 // "Network Connection (%@)" --> keychain "Name"
5712 interface_name
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
5713 if (interface_name
!= NULL
) {
5714 CFStringRef label_fmt
;
5716 label_fmt
= CFBundleCopyLocalizedString(bundle
,
5717 CFSTR("KEYCHAIN_DESCRIPTION_EAPOL_INTERFACE"),
5718 CFSTR("Network Connection (%@)"),
5720 label
= CFStringCreateWithFormat(NULL
, NULL
, label_fmt
, interface_name
);
5721 CFRelease(label_fmt
);
5723 label
= CFBundleCopyLocalizedString(bundle
,
5724 CFSTR("KEYCHAIN_DESCRIPTION_EAPOL"),
5725 CFSTR("Network Connection"),
5729 // "802.1X Password" --> keychain "Kind"
5730 description
= CFBundleCopyLocalizedString(bundle
,
5731 CFSTR("KEYCHAIN_KIND_EAPOL"),
5732 CFSTR("802.1X Password"),
5737 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
5739 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
5740 (description
!= NULL
) ? description
: CFSTR("802.1X Password"),
5745 CFMutableDictionaryRef newConfig
= NULL
;
5747 if (config
!= NULL
) {
5748 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
5750 newConfig
= CFDictionaryCreateMutable(NULL
,
5752 &kCFTypeDictionaryKeyCallBacks
,
5753 &kCFTypeDictionaryValueCallBacks
);
5755 CFDictionarySetValue(newConfig
,
5756 kEAPClientPropUserPasswordKeychainItemID
,
5758 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
5761 CFRelease(newConfig
);
5764 CFRelease(unique_id
);
5765 if (label
!= NULL
) CFRelease(label
);
5766 if (description
!= NULL
) CFRelease(description
);
5770 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
5771 SCNetworkServiceRef service
= NULL
;
5772 CFStringRef xauth_id
;
5774 // get configuration
5775 config
= SCNetworkInterfaceGetConfiguration(interface
);
5778 xauth_id
= copyXAuthID(config
, serviceID
);
5780 // get "Account", "Name", "Kind"
5781 if (config
!= NULL
) {
5782 // auth name --> keychain "Account"
5783 account
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthName
);
5785 // IPSec [user defined] "name" --> keychain "Name"
5786 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
5789 if (label
== NULL
) {
5790 // service name --> keychain "Name"
5791 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
5796 label
= SCNetworkServiceGetName(service
);
5797 if (label
== NULL
) {
5798 // interface name --> keychain "Name"
5799 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
5803 if (bundle
!= NULL
) {
5804 // "IPSec XAuth Password" --> keychain "Kind"
5805 description
= CFBundleCopyLocalizedString(bundle
,
5806 CFSTR("KEYCHAIN_KIND_IPSEC_XAUTH_PASSWORD"),
5807 CFSTR("IPSec XAuth Password"),
5812 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
5814 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
5815 (description
!= NULL
) ? description
: CFSTR("IPSec XAuth Password"),
5820 CFMutableDictionaryRef newConfig
;
5822 if (config
!= NULL
) {
5823 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
5825 newConfig
= CFDictionaryCreateMutable(NULL
,
5827 &kCFTypeDictionaryKeyCallBacks
,
5828 &kCFTypeDictionaryValueCallBacks
);
5830 CFDictionarySetValue(newConfig
,
5831 kSCPropNetIPSecXAuthPassword
,
5833 CFDictionarySetValue(newConfig
,
5834 kSCPropNetIPSecXAuthPasswordEncryption
,
5835 kSCValNetIPSecXAuthPasswordEncryptionKeychain
);
5836 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
5837 CFRelease(newConfig
);
5840 CFRelease(xauth_id
);
5841 if (description
!= NULL
) CFRelease(description
);
5842 if (service
!= NULL
) CFRelease(service
);
5846 case kSCNetworkInterfacePasswordTypeVPN
: {
5847 SCNetworkServiceRef service
= NULL
;
5850 // get configuration
5851 config
= SCNetworkInterfaceGetConfiguration(interface
);
5854 vpn_id
= getPasswordID(config
, serviceID
);
5856 // get "Account", "Name", "Kind"
5857 if (config
!= NULL
) {
5858 // auth name --> keychain "Account"
5859 account
= CFDictionaryGetValue(config
, kSCPropNetVPNAuthName
);
5861 // VPN [user defined] "name" --> keychain "Name"
5862 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
5865 if (label
== NULL
) {
5866 // service name --> keychain "Name"
5867 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
5872 label
= SCNetworkServiceGetName(service
);
5873 if (label
== NULL
) {
5874 // interface name --> keychain "Name"
5875 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
5879 if (bundle
!= NULL
) {
5880 // "VPN Password" --> keychain "Kind"
5881 description
= CFBundleCopyLocalizedString(bundle
,
5882 CFSTR("KEYCHAIN_KIND_VPN_PASSWORD"),
5883 CFSTR("VPN Password"),
5888 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
5890 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
5891 (description
!= NULL
) ? description
: CFSTR("VPN Password"),
5896 CFMutableDictionaryRef newConfig
;
5898 if (config
!= NULL
) {
5899 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
5901 newConfig
= CFDictionaryCreateMutable(NULL
,
5903 &kCFTypeDictionaryKeyCallBacks
,
5904 &kCFTypeDictionaryValueCallBacks
);
5906 CFDictionarySetValue(newConfig
,
5907 kSCPropNetVPNAuthPassword
,
5909 CFDictionarySetValue(newConfig
,
5910 kSCPropNetVPNAuthPasswordEncryption
,
5911 kSCValNetVPNAuthPasswordEncryptionKeychain
);
5912 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
5913 CFRelease(newConfig
);
5916 if (description
!= NULL
) CFRelease(description
);
5917 if (service
!= NULL
) CFRelease(service
);
5922 _SCErrorSet(kSCStatusInvalidArgument
);
5931 #pragma mark SCNetworkInterface [InterfaceNamer] SPIs
5935 _SCNetworkInterfaceCopyInterfaceInfo(SCNetworkInterfaceRef interface
)
5937 CFMutableDictionaryRef info
;
5938 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5941 info
= CFDictionaryCreateMutable(NULL
,
5943 &kCFTypeDictionaryKeyCallBacks
,
5944 &kCFTypeDictionaryValueCallBacks
);
5946 // add non-localized interface name
5947 name
= __SCNetworkInterfaceGetNonLocalizedDisplayName(interface
);
5949 CFDictionaryAddValue(info
, kSCPropUserDefinedName
, name
);
5953 if ((interfacePrivate
->usb
.vid
!= NULL
) || (interfacePrivate
->usb
.pid
!= NULL
)) {
5954 if (interfacePrivate
->usb
.name
!= NULL
) {
5955 CFDictionaryAddValue(info
, CFSTR(kUSBProductString
), interfacePrivate
->usb
.name
);
5957 if (interfacePrivate
->usb
.vid
!= NULL
) {
5958 CFDictionaryAddValue(info
, CFSTR(kUSBVendorID
), interfacePrivate
->usb
.vid
);
5960 if (interfacePrivate
->usb
.pid
!= NULL
) {
5961 CFDictionaryAddValue(info
, CFSTR(kUSBProductID
), interfacePrivate
->usb
.pid
);
5965 if (CFDictionaryGetCount(info
) == 0) {
5966 // do not return an empty dictionary
5975 SCNetworkInterfaceRef
5976 _SCNetworkInterfaceCreateWithIONetworkInterfaceObject(io_object_t if_obj
)
5978 SCNetworkInterfaceRef interface
= NULL
;
5980 /* initialize runtime */
5981 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5983 if (IOObjectConformsTo(if_obj
, kIONetworkInterfaceClass
)) {
5984 interface
= createInterface(if_obj
, processNetworkInterface
);
5985 } else if (IOObjectConformsTo(if_obj
, kIOSerialBSDServiceValue
)) {
5986 interface
= createInterface(if_obj
, processSerialInterface
);
5994 _SCNetworkInterfaceGetConfigurationAction(SCNetworkInterfaceRef interface
)
5996 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5998 return interfacePrivate
->configurationAction
;
6003 _SCNetworkInterfaceGetHardwareAddress(SCNetworkInterfaceRef interface
)
6005 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6007 return interfacePrivate
->address
;
6012 _SCNetworkInterfaceGetIOInterfaceType(SCNetworkInterfaceRef interface
)
6014 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6016 return interfacePrivate
->type
;
6021 _SCNetworkInterfaceGetIOInterfaceUnit(SCNetworkInterfaceRef interface
)
6023 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6025 return interfacePrivate
->unit
;
6030 _SCNetworkInterfaceGetIOPath(SCNetworkInterfaceRef interface
)
6032 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6034 return interfacePrivate
->path
;
6039 _SCNetworkInterfaceGetIORegistryEntryID(SCNetworkInterfaceRef interface
)
6041 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6043 return interfacePrivate
->entryID
;
6048 _SCNetworkInterfaceIsBuiltin(SCNetworkInterfaceRef interface
)
6050 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6052 return interfacePrivate
->builtin
;
6057 #pragma mark SCNetworkInterface SPIs
6061 _SCNetworkInterfaceCopySlashDevPath(SCNetworkInterfaceRef interface
)
6063 io_registry_entry_t device
;
6064 io_iterator_t device_iterator
= MACH_PORT_NULL
;
6065 CFStringRef device_path
= NULL
;
6066 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6068 CFStringRef match_keys
[2];
6069 CFTypeRef match_vals
[2];
6070 CFDictionaryRef match_dict
;
6071 CFDictionaryRef matching
;
6073 if (interfacePrivate
->entity_device
== NULL
) {
6077 if (interfacePrivate
->entity_device_unique
== NULL
) {
6081 match_keys
[0] = CFSTR(kIOTTYBaseNameKey
);
6082 match_vals
[0] = interfacePrivate
->entity_device
;
6083 match_dict
= CFDictionaryCreate(NULL
,
6084 (const void **)match_keys
,
6085 (const void **)match_vals
,
6087 &kCFTypeDictionaryKeyCallBacks
,
6088 &kCFTypeDictionaryValueCallBacks
);
6090 match_keys
[0] = CFSTR(kIOProviderClassKey
);
6091 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
6092 match_keys
[1] = CFSTR(kIOPropertyMatchKey
);
6093 match_vals
[1] = match_dict
;
6094 matching
= CFDictionaryCreate(NULL
,
6095 (const void **)match_keys
,
6096 (const void **)match_vals
,
6097 sizeof(match_keys
)/sizeof(match_keys
[0]),
6098 &kCFTypeDictionaryKeyCallBacks
,
6099 &kCFTypeDictionaryValueCallBacks
);
6100 CFRelease(match_dict
);
6102 // note: this "matching" dictionary will be consumed by the call to IOServiceGetMatchingServices
6103 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &device_iterator
);
6104 if (kr
!= kIOReturnSuccess
) {
6105 SCLog(TRUE
, LOG_DEBUG
, CFSTR("IOServiceGetMatchingServices() failed, kr = 0x%x"), kr
);
6109 while ((device_path
== NULL
) &&
6110 ((device
= IOIteratorNext(device_iterator
)) != MACH_PORT_NULL
)) {
6111 CFDictionaryRef overrides
;
6113 overrides
= IORegistryEntrySearchCFProperty(device
,
6115 kSCNetworkInterfaceNetworkConfigurationOverridesKey
,
6117 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
6118 if (overrides
!= NULL
) {
6119 CFDictionaryRef modemOverrides
;
6121 modemOverrides
= CFDictionaryGetValue(overrides
, kSCEntNetModem
);
6122 if (modemOverrides
!= NULL
) {
6123 CFRetain(modemOverrides
);
6125 CFRelease(overrides
);
6126 overrides
= modemOverrides
;
6128 if (overrides
== NULL
) {
6129 overrides
= IORegistryEntrySearchCFProperty(device
,
6131 CFSTR("DeviceModemOverrides"),
6133 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
6135 if (overrides
!= NULL
) {
6136 if (isA_CFDictionary(overrides
)) {
6137 CFStringRef matchIdentifier
;
6139 matchIdentifier
= CFDictionaryGetValue(overrides
, CFSTR("UniqueIdentifier"));
6140 if (isA_CFString(matchIdentifier
) &&
6141 CFEqual(interfacePrivate
->entity_device_unique
, matchIdentifier
)) {
6142 device_path
= IORegistryEntryCreateCFProperty(device
,
6143 CFSTR(kIOTTYDeviceKey
),
6148 CFRelease(overrides
);
6150 IOObjectRelease(device
);
6153 IOObjectRelease(device_iterator
);
6157 if (device_path
== NULL
) {
6158 // if we haven't found an exact match to our UniqueIdentifier
6159 // so we simply return the base name.
6160 device_path
= SCNetworkInterfaceGetBSDName(interface
);
6161 if (device_path
!= NULL
) {
6162 CFRetain(device_path
);
6171 _SCNetworkInterfaceIsBluetoothPAN(SCNetworkInterfaceRef interface
)
6173 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6175 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_GN
);
6180 _SCNetworkInterfaceIsBluetoothPAN_NAP(SCNetworkInterfaceRef interface
)
6182 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6184 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_NAP
);
6189 _SCNetworkInterfaceIsBluetoothP2P(SCNetworkInterfaceRef interface
)
6191 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6193 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_U
);
6198 _SCNetworkInterfaceIsHiddenConfiguration(SCNetworkInterfaceRef interface
)
6200 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6202 return interfacePrivate
->hidden
;
6207 _SCNetworkInterfaceIsModemV92(SCNetworkInterfaceRef interface
)
6209 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6211 return interfacePrivate
->modemIsV92
;
6216 _SCNetworkInterfaceIsTethered(SCNetworkInterfaceRef interface
)
6218 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6220 return (interfacePrivate
->sort_order
== kSortTethered
);
6225 #pragma mark SCNetworkInterface [internal] SPIs
6229 SCNetworkInterfacePrivateRef
6230 __SCNetworkInterfaceCreateCopy(CFAllocatorRef allocator
,
6231 SCNetworkInterfaceRef interface
,
6232 SCPreferencesRef prefs
,
6233 CFStringRef serviceID
)
6235 SCNetworkInterfacePrivateRef oldPrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6236 SCNetworkInterfacePrivateRef newPrivate
;
6238 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
6239 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
6241 if (interface
== kSCNetworkInterfaceIPv4
) {
6242 return (SCNetworkInterfacePrivateRef
)CFRetain(interface
);
6245 newPrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, prefs
, serviceID
);
6246 newPrivate
->interface_type
= oldPrivate
->interface_type
;
6247 if (oldPrivate
->interface
!= NULL
) {
6248 newPrivate
->interface
= (SCNetworkInterfaceRef
)__SCNetworkInterfaceCreateCopy(NULL
, // allocator
6249 oldPrivate
->interface
, // interface
6250 prefs
, // [new] prefs
6251 serviceID
); // [new] serviceID
6253 if (oldPrivate
->name
!= NULL
) {
6254 newPrivate
->name
= CFRetain(oldPrivate
->name
);
6256 if (oldPrivate
->localized_name
!= NULL
) {
6257 newPrivate
->localized_name
= CFRetain(oldPrivate
->localized_name
);
6259 newPrivate
->localized_key
= oldPrivate
->localized_key
;
6260 if (oldPrivate
->localized_arg1
!= NULL
) {
6261 newPrivate
->localized_arg1
= CFRetain(oldPrivate
->localized_arg1
);
6263 if (oldPrivate
->localized_arg2
!= NULL
) {
6264 newPrivate
->localized_arg2
= CFRetain(oldPrivate
->localized_arg2
);
6266 if (oldPrivate
->unsaved
!= NULL
) {
6267 newPrivate
->unsaved
= CFDictionaryCreateMutableCopy(NULL
, 0, oldPrivate
->unsaved
);
6269 if (oldPrivate
->entity_device
!= NULL
) {
6270 newPrivate
->entity_device
= CFRetain(oldPrivate
->entity_device
);
6272 if (oldPrivate
->entity_device_unique
!= NULL
) {
6273 newPrivate
->entity_device_unique
= CFRetain(oldPrivate
->entity_device_unique
);
6275 newPrivate
->entity_type
= oldPrivate
->entity_type
;
6276 newPrivate
->entity_subtype
= oldPrivate
->entity_subtype
;
6277 if (oldPrivate
->supported_interface_types
!= NULL
) {
6278 newPrivate
->supported_interface_types
= CFArrayCreateMutableCopy(NULL
, 0, oldPrivate
->supported_interface_types
);
6280 if (oldPrivate
->supported_protocol_types
!= NULL
) {
6281 newPrivate
->supported_protocol_types
= CFArrayCreateMutableCopy(NULL
, 0, oldPrivate
->supported_protocol_types
);
6283 if (oldPrivate
->address
!= NULL
) {
6284 newPrivate
->address
= CFRetain(oldPrivate
->address
);
6286 newPrivate
->builtin
= oldPrivate
->builtin
;
6287 if (oldPrivate
->configurationAction
!= NULL
) {
6288 newPrivate
->configurationAction
= CFRetain(oldPrivate
->configurationAction
);
6290 newPrivate
->hidden
= oldPrivate
->hidden
;
6291 if (oldPrivate
->location
!= NULL
) {
6292 newPrivate
->location
= CFRetain(oldPrivate
->location
);
6294 if (oldPrivate
->path
!= NULL
) {
6295 newPrivate
->path
= CFRetain(oldPrivate
->path
);
6297 newPrivate
->entryID
= oldPrivate
->entryID
;
6298 if (oldPrivate
->overrides
!= NULL
) {
6299 newPrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, oldPrivate
->overrides
);
6301 newPrivate
->modemIsV92
= oldPrivate
->modemIsV92
;
6302 if (oldPrivate
->type
!= NULL
) {
6303 newPrivate
->type
= CFRetain(oldPrivate
->type
);
6305 if (oldPrivate
->unit
!= NULL
) {
6306 newPrivate
->unit
= CFRetain(oldPrivate
->unit
);
6308 if (oldPrivate
->usb
.name
!= NULL
) {
6309 newPrivate
->usb
.name
= CFRetain(oldPrivate
->usb
.name
);
6311 if (oldPrivate
->usb
.vid
!= NULL
) {
6312 newPrivate
->usb
.vid
= CFRetain(oldPrivate
->usb
.vid
);
6314 if (oldPrivate
->usb
.pid
!= NULL
) {
6315 newPrivate
->usb
.pid
= CFRetain(oldPrivate
->usb
.pid
);
6317 newPrivate
->sort_order
= oldPrivate
->sort_order
;
6319 newPrivate
->supportsBond
= oldPrivate
->supportsBond
;
6320 if (oldPrivate
->bond
.interfaces
!= NULL
) {
6321 newPrivate
->bond
.interfaces
= CFRetain(oldPrivate
->bond
.interfaces
);
6323 if (oldPrivate
->bond
.mode
!= NULL
) {
6324 newPrivate
->bond
.mode
= CFRetain(oldPrivate
->bond
.mode
);
6326 if (oldPrivate
->bond
.options
!= NULL
) {
6327 newPrivate
->bond
.options
= CFRetain(oldPrivate
->bond
.options
);
6330 newPrivate
->supportsBridge
= oldPrivate
->supportsBridge
;
6331 if (oldPrivate
->bridge
.interfaces
!= NULL
) {
6332 newPrivate
->bridge
.interfaces
= CFRetain(oldPrivate
->bridge
.interfaces
);
6334 if (oldPrivate
->bridge
.options
!= NULL
) {
6335 newPrivate
->bridge
.options
= CFRetain(oldPrivate
->bridge
.options
);
6338 newPrivate
->supportsVLAN
= oldPrivate
->supportsVLAN
;
6339 if (oldPrivate
->vlan
.interface
!= NULL
) {
6340 newPrivate
->vlan
.interface
= CFRetain(oldPrivate
->vlan
.interface
);
6342 if (oldPrivate
->vlan
.tag
!= NULL
) {
6343 newPrivate
->vlan
.tag
= CFRetain(oldPrivate
->vlan
.tag
);
6345 if (oldPrivate
->vlan
.options
!= NULL
) {
6346 newPrivate
->vlan
.options
= CFRetain(oldPrivate
->vlan
.options
);
6355 __SCNetworkInterfaceCopyDeepConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
)
6357 CFMutableArrayRef configs
;
6359 configs
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
6361 while (interface
!= NULL
) {
6362 CFStringRef defaultType
;
6363 CFMutableDictionaryRef interfaceConfiguration
;
6365 interfaceConfiguration
= CFDictionaryCreateMutable(NULL
,
6367 &kCFTypeDictionaryKeyCallBacks
,
6368 &kCFTypeDictionaryValueCallBacks
);
6370 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
6371 if (defaultType
!= NULL
) {
6372 CFDictionaryRef config
;
6373 CFArrayRef extendedTypes
;
6376 config
= __SCNetworkInterfaceGetConfiguration(interface
, defaultType
);
6378 config
= __SCNetworkInterfaceGetDefaultConfiguration(set
, interface
);
6380 if (config
== NULL
) {
6381 config
= (CFDictionaryRef
)kCFNull
;
6383 CFDictionarySetValue(interfaceConfiguration
, defaultType
, config
);
6385 extendedTypes
= extendedConfigurationTypes(interface
);
6386 if (extendedTypes
!= NULL
) {
6390 n
= CFArrayGetCount(extendedTypes
);
6391 for (i
= 0; i
< n
; i
++) {
6392 CFStringRef extendedType
;
6394 extendedType
= CFArrayGetValueAtIndex(extendedTypes
, i
);
6395 config
= __SCNetworkInterfaceGetConfiguration(interface
, extendedType
);
6396 if (config
== NULL
) {
6397 config
= (CFDictionaryRef
)kCFNull
;
6399 CFDictionarySetValue(interfaceConfiguration
, extendedType
, config
);
6402 CFRelease(extendedTypes
);
6406 CFArrayAppendValue(configs
, interfaceConfiguration
);
6407 CFRelease(interfaceConfiguration
);
6409 interface
= SCNetworkInterfaceGetInterface(interface
);
6416 __private_extern__ Boolean
6417 __SCNetworkInterfaceIsMember(SCPreferencesRef prefs
, SCNetworkInterfaceRef interface
)
6419 CFArrayRef interfaces
;
6420 Boolean match
= FALSE
;
6421 CFMutableSetRef members
;
6423 members
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
6425 // add Bond [member] interfaces
6426 interfaces
= SCBondInterfaceCopyAll(prefs
);
6427 if (interfaces
!= NULL
) {
6428 __SCBondInterfaceListCollectMembers(interfaces
, members
);
6429 CFRelease(interfaces
);
6432 // add Bridge [member] interfaces
6433 interfaces
= SCBridgeInterfaceCopyAll(prefs
);
6434 if (interfaces
!= NULL
) {
6435 __SCBridgeInterfaceListCollectMembers(interfaces
, members
);
6436 CFRelease(interfaces
);
6439 if (CFSetGetCount(members
) == 0) {
6443 while (interface
!= NULL
) {
6444 match
= CFSetContainsValue(members
, interface
);
6446 // if the interface is a member of an
6447 // Ethernet Bond or Bridge
6451 interface
= SCNetworkInterfaceGetInterface(interface
);
6463 __SCNetworkInterfaceSetDeepConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
, CFArrayRef configs
)
6467 for (i
= 0; interface
!= NULL
; i
++) {
6468 CFStringRef defaultType
;
6469 CFDictionaryRef interfaceConfiguration
;
6471 interfaceConfiguration
= (configs
!= NULL
) ? CFArrayGetValueAtIndex(configs
, i
) : NULL
;
6473 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
6474 if (defaultType
!= NULL
) {
6475 CFDictionaryRef config
;
6476 CFArrayRef extendedTypes
;
6478 config
= (interfaceConfiguration
!= NULL
) ? CFDictionaryGetValue(interfaceConfiguration
, defaultType
)
6480 if (config
== (CFDictionaryRef
)kCFNull
) {
6484 // if service is not associated with the set
6485 if (!__SCNetworkInterfaceSetConfiguration(interface
, defaultType
, config
, TRUE
)) {
6486 SCLog(TRUE
, LOG_DEBUG
,
6487 CFSTR("__SCNetworkInterfaceSetDeepConfiguration __SCNetworkInterfaceSetConfiguration() failed, interface=%@, type=%@"),
6492 // apply default configuration to this set
6493 if (!__SCNetworkInterfaceSetDefaultConfiguration(set
, interface
, defaultType
, config
, TRUE
)) {
6494 SCLog(TRUE
, LOG_DEBUG
,
6495 CFSTR("__SCNetworkInterfaceSetDeepConfiguration __SCNetworkInterfaceSetDefaultConfiguration() failed, interface=%@, type=%@"),
6501 extendedTypes
= extendedConfigurationTypes(interface
);
6502 if (extendedTypes
!= NULL
) {
6506 n
= CFArrayGetCount(extendedTypes
);
6507 for (j
= 0; j
< n
; j
++) {
6508 CFStringRef extendedType
;
6510 extendedType
= CFArrayGetValueAtIndex(extendedTypes
, j
);
6511 config
= (interfaceConfiguration
!= NULL
) ? CFDictionaryGetValue(interfaceConfiguration
, extendedType
)
6513 if (config
== (CFDictionaryRef
)kCFNull
) {
6516 if (!__SCNetworkInterfaceSetConfiguration(interface
, extendedType
, config
, TRUE
)) {
6517 SCLog(TRUE
, LOG_DEBUG
,
6518 CFSTR("__SCNetworkInterfaceSetDeepConfiguration __SCNetworkInterfaceSetConfiguration() failed, interface=%@, type=%@"),
6524 CFRelease(extendedTypes
);
6528 interface
= SCNetworkInterfaceGetInterface(interface
);