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
183 { NULL
, 0, 0 }, // usb { name, vid, pid }
184 kSortUnknown
, // sort_order
185 FALSE
, // supportsBond
186 { NULL
, NULL
, NULL
}, // bond { interfaces, options, mode }
187 FALSE
, // supportsBridge
188 { NULL
, NULL
}, // bridge { interfaces, options }
189 FALSE
, // supportsVLAN
190 { NULL
, NULL
, NULL
} // vlan { interface, tag, options }
193 const SCNetworkInterfaceRef kSCNetworkInterfaceIPv4
= (SCNetworkInterfaceRef
)&__kSCNetworkInterfaceIPv4
;
195 static SCNetworkInterfacePrivate __kSCNetworkInterfaceLoopback
= {
196 INIT_CFRUNTIME_BASE(), // cfBase
197 NULL
, // interface type
199 NULL
, // localized name
200 NULL
, // localization key
201 NULL
, // localization arg1
202 NULL
, // localization arg2
203 NULL
, // [layered] interface
207 NULL
, // entity_device
208 NULL
, // entity_device_unique
210 NULL
, // entity_subtype
211 NULL
, // supported_interface_types
212 NULL
, // supported_protocol_types
214 NULL
, // addressString
216 NULL
, // configurationAction
224 { NULL
, 0, 0 }, // usb { name, vid, pid }
225 kSortUnknown
, // sort_order
226 FALSE
, // supportsBond
227 { NULL
, NULL
, NULL
}, // bond { interfaces, options, mode }
228 FALSE
, // supportsBridge
229 { NULL
, NULL
}, // bridge { interfaces, options }
230 FALSE
, // supportsVLAN
231 { NULL
, NULL
, NULL
} // vlan { interface, tag, options }
234 const SCNetworkInterfaceRef kSCNetworkInterfaceLoopback
= (SCNetworkInterfaceRef
)&__kSCNetworkInterfaceLoopback
;
236 static CFMutableSetRef vendor_interface_types
= NULL
;
239 #pragma mark SCNetworkInterface configuration details
248 #define doOverIP do6to4|doL2TP|doPPTP|doIPSec
253 #define doProxies 1<<4
254 #if !TARGET_OS_IPHONE
256 #else // !TARGET_OS_IPHONE
258 #endif // !TARGET_OS_IPHONE
260 static const struct {
261 const CFStringRef
*interface_type
;
262 const CFStringRef
*entity_hardware
;
263 Boolean per_interface_config
;
264 uint32_t supported_interfaces
;
265 const CFStringRef
*ppp_subtype
;
266 uint32_t supported_protocols
;
267 } configurations
[] = {
268 // interface type entity_hardware if config? interface types PPP sub-type interface protocols
269 // ===================================== ================= ========== =============== ======================================= =========================================
270 { &kSCNetworkInterfaceType6to4
, &kSCEntNet6to4
, FALSE
, doNone
, NULL
, doIPv6
},
271 { &kSCNetworkInterfaceTypeBluetooth
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
272 { &kSCNetworkInterfaceTypeBond
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
273 { &kSCNetworkInterfaceTypeBridge
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
274 { &kSCNetworkInterfaceTypeEthernet
, &kSCEntNetEthernet
, TRUE
, doPPP
, &kSCValNetInterfaceSubTypePPPoE
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
275 { &kSCNetworkInterfaceTypeFireWire
, &kSCEntNetFireWire
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
276 { &kSCNetworkInterfaceTypeIEEE80211
, &kSCEntNetAirPort
, TRUE
, doPPP
, &kSCValNetInterfaceSubTypePPPoE
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
277 { &kSCNetworkInterfaceTypeIPSec
, &kSCEntNetIPSec
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
278 { &kSCNetworkInterfaceTypeIrDA
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
279 { &kSCNetworkInterfaceTypeL2TP
, NULL
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypeL2TP
, doNone
},
280 { &kSCNetworkInterfaceTypeModem
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
281 { &kSCNetworkInterfaceTypePPP
, &kSCEntNetPPP
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
282 { &kSCNetworkInterfaceTypePPTP
, NULL
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPTP
, doNone
},
283 { &kSCNetworkInterfaceTypeSerial
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
284 { &kSCNetworkInterfaceTypeVLAN
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
285 { &kSCNetworkInterfaceTypeVPN
, &kSCEntNetVPN
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
286 { &kSCNetworkInterfaceTypeWWAN
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
287 // ===================================== ================= ========== =============== ======================================= =========================================
288 { &kSCNetworkInterfaceTypeLoopback
, NULL
, TRUE
, doNone
, NULL
, doIPv4
|doIPv6
},
289 // ===================================== ================= ========== =============== ======================================= =========================================
290 { &kSCNetworkInterfaceTypeIPv4
, NULL
, FALSE
, doOverIP
, NULL
, doNone
}
294 #define NETWORKINTERFACE_LOCALIZATIONS CFSTR("NetworkInterface")
295 static CFBundleRef bundle
= NULL
;
298 static CFTypeID __kSCNetworkInterfaceTypeID
= _kCFRuntimeNotATypeID
;
301 static const CFRuntimeClass __SCNetworkInterfaceClass
= {
303 "SCNetworkInterface", // className
306 __SCNetworkInterfaceDeallocate
, // dealloc
307 __SCNetworkInterfaceEqual
, // equal
308 __SCNetworkInterfaceHash
, // hash
309 NULL
, // copyFormattingDesc
310 __SCNetworkInterfaceCopyDescription
// copyDebugDesc
314 static pthread_once_t initialized
= PTHREAD_ONCE_INIT
;
315 static pthread_once_t iokit_quiet
= PTHREAD_ONCE_INIT
;
318 static mach_port_t masterPort
= MACH_PORT_NULL
;
322 __SCNetworkInterfaceCopyDescription(CFTypeRef cf
)
324 CFAllocatorRef allocator
= CFGetAllocator(cf
);
325 CFMutableStringRef result
;
326 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
328 result
= CFStringCreateMutable(allocator
, 0);
329 CFStringAppendFormat(result
, NULL
, CFSTR("<SCNetworkInterface %p [%p]> {"), cf
, allocator
);
330 CFStringAppendFormat(result
, NULL
, CFSTR("type = %@"), interfacePrivate
->interface_type
);
331 CFStringAppendFormat(result
, NULL
, CFSTR(", entity_device = %@"), interfacePrivate
->entity_device
);
332 if (interfacePrivate
->entity_device_unique
!= NULL
) {
333 CFStringAppendFormat(result
, NULL
, CFSTR("+%@"), interfacePrivate
->entity_device_unique
);
335 CFStringAppendFormat(result
, NULL
, CFSTR(", entity_type = %@"), interfacePrivate
->entity_type
);
336 if (interfacePrivate
->entity_subtype
!= NULL
) {
337 CFStringAppendFormat(result
, NULL
, CFSTR(" / %@"), interfacePrivate
->entity_subtype
);
339 if (interfacePrivate
->name
!= NULL
) {
340 CFStringAppendFormat(result
, NULL
, CFSTR(", name = %@"), interfacePrivate
->name
);
342 if (interfacePrivate
->localized_name
!= NULL
) {
343 CFStringAppendFormat(result
, NULL
, CFSTR(", name(l) = %@"), interfacePrivate
->localized_name
);
345 if (interfacePrivate
->localized_key
!= NULL
) {
346 CFStringAppendFormat(result
, NULL
, CFSTR(", name(k) = \"%@\""), interfacePrivate
->localized_key
);
347 if (interfacePrivate
->localized_arg1
!= NULL
) {
348 CFStringAppendFormat(result
, NULL
, CFSTR("+\"%@\""), interfacePrivate
->localized_arg1
);
350 if (interfacePrivate
->localized_arg2
!= NULL
) {
351 CFStringAppendFormat(result
, NULL
, CFSTR("+\"%@\""), interfacePrivate
->localized_arg2
);
355 if (interfacePrivate
->address
!= NULL
) {
360 CFStringAppendFormat(result
, NULL
, CFSTR(", address = 0x"));
362 data
= CFDataGetBytePtr(interfacePrivate
->address
);
363 dataLen
= CFDataGetLength(interfacePrivate
->address
);
364 for (i
= 0; i
< dataLen
; i
++) {
365 CFStringAppendFormat(result
, NULL
, CFSTR("%02x"), data
[i
]);
368 CFStringAppendFormat(result
, NULL
, CFSTR(", builtin = %s"), interfacePrivate
->builtin
? "TRUE" : "FALSE");
369 if (interfacePrivate
->hidden
) {
370 CFStringAppendFormat(result
, NULL
, CFSTR(", hidden = TRUE"));
372 if (interfacePrivate
->modemIsV92
) {
373 CFStringAppendFormat(result
, NULL
, CFSTR(", v.92"));
375 if (interfacePrivate
->location
!= NULL
) {
376 CFStringAppendFormat(result
, NULL
, CFSTR(", location = %@"), interfacePrivate
->location
);
378 if (interfacePrivate
->path
!= NULL
) {
379 CFStringAppendFormat(result
, NULL
, CFSTR(", path = %@"), interfacePrivate
->path
);
381 if (interfacePrivate
->type
!= NULL
) {
382 CFStringAppendFormat(result
, NULL
, CFSTR(", type = %@"), interfacePrivate
->type
);
384 if (interfacePrivate
->unit
!= NULL
) {
385 CFStringAppendFormat(result
, NULL
, CFSTR(", unit = %@"), interfacePrivate
->unit
);
387 if ((interfacePrivate
->usb
.vid
!= NULL
) || (interfacePrivate
->usb
.pid
!= NULL
)) {
391 if (!isA_CFNumber(interfacePrivate
->usb
.pid
) ||
392 !CFNumberGetValue(interfacePrivate
->usb
.vid
, kCFNumberIntType
, &pid
)) {
395 if (!isA_CFNumber(interfacePrivate
->usb
.vid
) ||
396 !CFNumberGetValue(interfacePrivate
->usb
.vid
, kCFNumberIntType
, &vid
)) {
400 if (interfacePrivate
->usb
.name
!= NULL
) {
401 CFStringAppendFormat(result
, NULL
, CFSTR(", USB name = %@"),
402 interfacePrivate
->usb
.name
);
405 CFStringAppendFormat(result
, NULL
, CFSTR(", USB vid/pid = 0x%0x/0x%0x"),
406 interfacePrivate
->usb
.vid
,
407 interfacePrivate
->usb
.pid
);
409 if (interfacePrivate
->configurationAction
!= NULL
) {
410 CFStringAppendFormat(result
, NULL
, CFSTR(", action = %@"), interfacePrivate
->configurationAction
);
412 if (interfacePrivate
->overrides
!= NULL
) {
413 CFStringAppendFormat(result
, NULL
, CFSTR(", overrides = %p"), interfacePrivate
->overrides
);
415 CFStringAppendFormat(result
, NULL
, CFSTR(", order = %d"), interfacePrivate
->sort_order
);
416 if (interfacePrivate
->prefs
!= NULL
) {
417 CFStringAppendFormat(result
, NULL
, CFSTR(", prefs = %p"), interfacePrivate
->prefs
);
419 if (interfacePrivate
->serviceID
!= NULL
) {
420 CFStringAppendFormat(result
, NULL
, CFSTR(", service = %@"), interfacePrivate
->serviceID
);
422 if (interfacePrivate
->interface
!= NULL
) {
423 CFStringAppendFormat(result
, NULL
, CFSTR(", interface = %@"), interfacePrivate
->interface
);
425 if (interfacePrivate
->unsaved
!= NULL
) {
426 CFStringAppendFormat(result
, NULL
, CFSTR(", unsaved = %@"), interfacePrivate
->unsaved
);
429 if (interfacePrivate
->bond
.interfaces
!= NULL
) {
433 n
= CFArrayGetCount(interfacePrivate
->bond
.interfaces
);
434 for (i
= 0; i
< n
; i
++) {
435 SCNetworkInterfaceRef member
;
437 member
= CFArrayGetValueAtIndex(interfacePrivate
->bond
.interfaces
, i
);
438 CFStringAppendFormat(result
, NULL
,
440 (i
== 0) ? ", interfaces = " : ", ",
441 SCNetworkInterfaceGetBSDName(member
));
444 if (interfacePrivate
->bond
.mode
!= NULL
) {
445 CFStringAppendFormat(result
, NULL
, CFSTR(", mode = %@"), interfacePrivate
->bond
.mode
);
447 if (interfacePrivate
->bond
.options
!= NULL
) {
448 CFStringAppendFormat(result
, NULL
, CFSTR(", options = %@"), interfacePrivate
->bond
.options
);
451 if (interfacePrivate
->bridge
.interfaces
!= NULL
) {
455 n
= CFArrayGetCount(interfacePrivate
->bridge
.interfaces
);
456 for (i
= 0; i
< n
; i
++) {
457 SCNetworkInterfaceRef member
;
459 member
= CFArrayGetValueAtIndex(interfacePrivate
->bridge
.interfaces
, i
);
460 CFStringAppendFormat(result
, NULL
,
462 (i
== 0) ? ", interfaces = " : ", ",
463 SCNetworkInterfaceGetBSDName(member
));
466 if (interfacePrivate
->bridge
.options
!= NULL
) {
467 CFStringAppendFormat(result
, NULL
, CFSTR(", options = %@"), interfacePrivate
->bridge
.options
);
470 if (interfacePrivate
->vlan
.interface
!= NULL
) {
471 CFStringAppendFormat(result
, NULL
,
472 CFSTR(", interface = %@"),
473 SCNetworkInterfaceGetBSDName(interfacePrivate
->vlan
.interface
));
475 if (interfacePrivate
->vlan
.tag
!= NULL
) {
476 CFStringAppendFormat(result
, NULL
, CFSTR(", tag = %@"), interfacePrivate
->vlan
.tag
);
478 if (interfacePrivate
->vlan
.options
!= NULL
) {
479 CFStringAppendFormat(result
, NULL
, CFSTR(", options = %@"), interfacePrivate
->vlan
.options
);
482 CFStringAppendFormat(result
, NULL
, CFSTR("}"));
489 __SCNetworkInterfaceDeallocate(CFTypeRef cf
)
491 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
493 /* release resources */
495 if (interfacePrivate
->name
!= NULL
)
496 CFRelease(interfacePrivate
->name
);
498 if (interfacePrivate
->localized_name
!= NULL
)
499 CFRelease(interfacePrivate
->localized_name
);
501 if (interfacePrivate
->localized_arg1
!= NULL
)
502 CFRelease(interfacePrivate
->localized_arg1
);
504 if (interfacePrivate
->localized_arg2
!= NULL
)
505 CFRelease(interfacePrivate
->localized_arg2
);
507 if (interfacePrivate
->interface
!= NULL
)
508 CFRelease(interfacePrivate
->interface
);
510 if (interfacePrivate
->prefs
!= NULL
)
511 CFRelease(interfacePrivate
->prefs
);
513 if (interfacePrivate
->serviceID
!= NULL
)
514 CFRelease(interfacePrivate
->serviceID
);
516 if (interfacePrivate
->unsaved
!= NULL
)
517 CFRelease(interfacePrivate
->unsaved
);
519 if (interfacePrivate
->entity_device
!= NULL
)
520 CFRelease(interfacePrivate
->entity_device
);
522 if (interfacePrivate
->entity_device_unique
!= NULL
)
523 CFRelease(interfacePrivate
->entity_device_unique
);
525 if (interfacePrivate
->supported_interface_types
!= NULL
)
526 CFRelease(interfacePrivate
->supported_interface_types
);
528 if (interfacePrivate
->supported_protocol_types
!= NULL
)
529 CFRelease(interfacePrivate
->supported_protocol_types
);
531 if (interfacePrivate
->address
!= NULL
)
532 CFRelease(interfacePrivate
->address
);
534 if (interfacePrivate
->addressString
!= NULL
)
535 CFRelease(interfacePrivate
->addressString
);
537 if (interfacePrivate
->configurationAction
!= NULL
)
538 CFRelease(interfacePrivate
->configurationAction
);
540 if (interfacePrivate
->location
!= NULL
)
541 CFRelease(interfacePrivate
->location
);
543 if (interfacePrivate
->path
!= NULL
)
544 CFRelease(interfacePrivate
->path
);
546 if (interfacePrivate
->overrides
!= NULL
)
547 CFRelease(interfacePrivate
->overrides
);
549 if (interfacePrivate
->type
!= NULL
)
550 CFRelease(interfacePrivate
->type
);
552 if (interfacePrivate
->unit
!= NULL
)
553 CFRelease(interfacePrivate
->unit
);
555 if (interfacePrivate
->usb
.name
!= NULL
)
556 CFRelease(interfacePrivate
->usb
.name
);
558 if (interfacePrivate
->usb
.pid
!= NULL
)
559 CFRelease(interfacePrivate
->usb
.pid
);
561 if (interfacePrivate
->usb
.vid
!= NULL
)
562 CFRelease(interfacePrivate
->usb
.vid
);
564 if (interfacePrivate
->bond
.interfaces
!= NULL
)
565 CFRelease(interfacePrivate
->bond
.interfaces
);
567 if (interfacePrivate
->bond
.mode
!= NULL
)
568 CFRelease(interfacePrivate
->bond
.mode
);
570 if (interfacePrivate
->bond
.options
!= NULL
)
571 CFRelease(interfacePrivate
->bond
.options
);
573 if (interfacePrivate
->bridge
.interfaces
!= NULL
)
574 CFRelease(interfacePrivate
->bridge
.interfaces
);
576 if (interfacePrivate
->bridge
.options
!= NULL
)
577 CFRelease(interfacePrivate
->bridge
.options
);
579 if (interfacePrivate
->vlan
.interface
!= NULL
)
580 CFRelease(interfacePrivate
->vlan
.interface
);
582 if (interfacePrivate
->vlan
.tag
!= NULL
)
583 CFRelease(interfacePrivate
->vlan
.tag
);
585 if (interfacePrivate
->vlan
.options
!= NULL
)
586 CFRelease(interfacePrivate
->vlan
.options
);
593 __SCNetworkInterfaceEqual(CFTypeRef cf1
, CFTypeRef cf2
)
595 SCNetworkInterfacePrivateRef if1
= (SCNetworkInterfacePrivateRef
)cf1
;
596 SCNetworkInterfacePrivateRef if2
= (SCNetworkInterfacePrivateRef
)cf2
;
601 if (!CFEqual(if1
->interface_type
, if2
->interface_type
)) {
602 return FALSE
; // if not the same interface type
605 if (!_SC_CFEqual(if1
->entity_device
, if2
->entity_device
)) {
606 return FALSE
; // if not the same device
609 if ((if1
->entity_device_unique
!= NULL
) && (if2
->entity_device_unique
!= NULL
)) {
610 if (!_SC_CFEqual(if1
->entity_device_unique
, if2
->entity_device_unique
)) {
611 return FALSE
; // if not the same device unique identifier
613 } else if ((if1
->entity_device_unique
!= NULL
) || (if2
->entity_device_unique
!= NULL
)) {
617 name1
= __SCNetworkInterfaceGetNonLocalizedDisplayName((SCNetworkInterfaceRef
)if1
);
618 name2
= __SCNetworkInterfaceGetNonLocalizedDisplayName((SCNetworkInterfaceRef
)if2
);
619 if ((name1
!= NULL
) && (name2
!= NULL
) && !_SC_CFEqual(name1
, name2
)) {
620 return FALSE
; // if same device but not the same display name
624 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeBond
)) {
625 if (!_SC_CFEqual(if1
->bond
.interfaces
, if2
->bond
.interfaces
)) {
626 return FALSE
; // if not the same interfaces
628 if (!_SC_CFEqual(if1
->bond
.mode
, if2
->bond
.mode
)) {
629 return FALSE
; // if not the same mode
633 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeBridge
)) {
634 if (!_SC_CFEqual(if1
->bridge
.interfaces
, if2
->bridge
.interfaces
)) {
635 return FALSE
; // if not the same interfaces
639 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeVLAN
)) {
640 if (!_SC_CFEqual(if1
->vlan
.interface
, if2
->vlan
.interface
)) {
641 return FALSE
; // if not the same physical interface
643 if (!_SC_CFEqual(if1
->vlan
.tag
, if2
->vlan
.tag
)) {
644 return FALSE
; // if not the same tag
648 if (!_SC_CFEqual(if1
->interface
, if2
->interface
)) {
649 return FALSE
; // if not the same layering
657 __SCNetworkInterfaceHash(CFTypeRef cf
)
660 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
662 if (interfacePrivate
->entity_device
!= NULL
) {
663 if (interfacePrivate
->entity_device_unique
== NULL
) {
664 hash
= CFHash(interfacePrivate
->entity_device
);
668 str
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@+%@"),
669 interfacePrivate
->entity_device
,
670 interfacePrivate
->entity_device_unique
);
681 __SCNetworkInterfaceInitialize(void)
686 __kSCNetworkInterfaceTypeID
= _CFRuntimeRegisterClass(&__SCNetworkInterfaceClass
);
688 // initialize __kSCNetworkInterfaceIPv4
689 _CFRuntimeInitStaticInstance(&__kSCNetworkInterfaceIPv4
, __kSCNetworkInterfaceTypeID
);
690 __kSCNetworkInterfaceIPv4
.interface_type
= kSCNetworkInterfaceTypeIPv4
;
691 __kSCNetworkInterfaceIPv4
.localized_key
= CFSTR("ipv4");
693 // initialize __kSCNetworkInterfaceLoopback
694 _CFRuntimeInitStaticInstance(&__kSCNetworkInterfaceLoopback
, __kSCNetworkInterfaceTypeID
);
695 __kSCNetworkInterfaceLoopback
.interface_type
= kSCNetworkInterfaceTypeLoopback
;
696 __kSCNetworkInterfaceLoopback
.localized_key
= CFSTR("loopback");
697 __kSCNetworkInterfaceLoopback
.entity_device
= CFRetain(CFSTR("lo0"));
698 __kSCNetworkInterfaceLoopback
.entity_type
= kSCValNetInterfaceTypeLoopback
;
700 // get CFBundleRef for SystemConfiguration.framework
701 bundle
= _SC_CFBundleGet();
703 // get mach port used to communication with IOKit
704 kr
= IOMasterPort(MACH_PORT_NULL
, &masterPort
);
705 if (kr
!= KERN_SUCCESS
) {
706 SCLog(TRUE
, LOG_DEBUG
,
707 CFSTR("__SCNetworkInterfaceInitialize(), could not get IOMasterPort, kr = 0x%x"),
716 SCNetworkInterfacePrivateRef
717 __SCNetworkInterfaceCreatePrivate(CFAllocatorRef allocator
,
718 SCNetworkInterfaceRef interface
,
719 SCPreferencesRef prefs
,
720 CFStringRef serviceID
,
723 SCNetworkInterfacePrivateRef interfacePrivate
;
726 /* initialize runtime */
727 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
729 /* allocate target */
730 size
= sizeof(SCNetworkInterfacePrivate
) - sizeof(CFRuntimeBase
);
731 interfacePrivate
= (SCNetworkInterfacePrivateRef
)_CFRuntimeCreateInstance(allocator
,
732 __kSCNetworkInterfaceTypeID
,
735 if (interfacePrivate
== NULL
) {
739 interfacePrivate
->interface_type
= NULL
;
740 interfacePrivate
->name
= NULL
;
741 interfacePrivate
->localized_name
= NULL
;
742 interfacePrivate
->localized_key
= NULL
;
743 interfacePrivate
->localized_arg1
= NULL
;
744 interfacePrivate
->localized_arg2
= NULL
;
745 interfacePrivate
->interface
= (interface
!= NULL
) ? CFRetain(interface
) : NULL
;
746 interfacePrivate
->prefs
= (prefs
!= NULL
) ? CFRetain(prefs
) : NULL
;
747 interfacePrivate
->serviceID
= (serviceID
!= NULL
) ? CFRetain(serviceID
) : NULL
;
748 interfacePrivate
->unsaved
= NULL
;
749 interfacePrivate
->entity_device
= NULL
;
750 interfacePrivate
->entity_device_unique
= NULL
;
751 interfacePrivate
->entity_type
= NULL
;
752 interfacePrivate
->entity_subtype
= NULL
;
753 interfacePrivate
->supported_interface_types
= NULL
;
754 interfacePrivate
->supported_protocol_types
= NULL
;
755 interfacePrivate
->address
= NULL
;
756 interfacePrivate
->addressString
= NULL
;
757 interfacePrivate
->builtin
= FALSE
;
758 interfacePrivate
->configurationAction
= NULL
;
759 interfacePrivate
->path
= (path
!= NULL
) ? CFStringCreateWithCString(NULL
, path
, kCFStringEncodingUTF8
)
761 interfacePrivate
->location
= NULL
;
762 interfacePrivate
->overrides
= NULL
;
763 interfacePrivate
->modemIsV92
= FALSE
;
764 interfacePrivate
->type
= NULL
;
765 interfacePrivate
->unit
= NULL
;
766 interfacePrivate
->usb
.name
= NULL
;
767 interfacePrivate
->usb
.vid
= NULL
;
768 interfacePrivate
->usb
.pid
= NULL
;
769 interfacePrivate
->sort_order
= kSortUnknown
;
771 interfacePrivate
->supportsBond
= FALSE
;
772 interfacePrivate
->bond
.interfaces
= NULL
;
773 interfacePrivate
->bond
.mode
= NULL
;
774 interfacePrivate
->bond
.options
= NULL
;
776 interfacePrivate
->supportsBridge
= FALSE
;
777 interfacePrivate
->bridge
.interfaces
= NULL
;
778 interfacePrivate
->bridge
.options
= NULL
;
780 interfacePrivate
->supportsVLAN
= FALSE
;
781 interfacePrivate
->vlan
.interface
= NULL
;
782 interfacePrivate
->vlan
.tag
= NULL
;
783 interfacePrivate
->vlan
.options
= NULL
;
785 return interfacePrivate
;
791 __SCNetworkInterfaceSupportsVLAN(CFStringRef bsd_if
)
795 struct if_msghdr
* ifm
;
796 char * if_name
= NULL
;
797 unsigned int if_index
;
799 Boolean vlanOK
= FALSE
;
801 // get the interface index
802 if_name
= _SC_cfstring_to_cstring(bsd_if
, NULL
, 0, kCFStringEncodingASCII
);
803 if (if_name
== NULL
) {
804 return FALSE
; // if conversion error
806 if_index
= if_nametoindex(if_name
);
808 goto done
; // if unknown interface
811 // get information for the specified interface
816 mib
[4] = NET_RT_IFLIST
;
817 mib
[5] = if_index
; /* ask for exactly one interface */
819 if (sysctl(mib
, 6, NULL
, &buf_len
, NULL
, 0) == -1) {
820 SCLog(TRUE
, LOG_ERR
, CFSTR("sysctl() size failed: %s"), strerror(errno
));
823 buf
= CFAllocatorAllocate(NULL
, buf_len
, 0);
824 if (sysctl(mib
, 6, buf
, &buf_len
, NULL
, 0) == -1) {
825 SCLog(TRUE
, LOG_ERR
, CFSTR("sysctl() failed: %s"), strerror(errno
));
829 // check the link type and hwassist flags
830 ifm
= (struct if_msghdr
*)buf
;
831 switch (ifm
->ifm_type
) {
833 #if defined(IF_HWASSIST_VLAN_TAGGING) && defined(IF_HWASSIST_VLAN_MTU)
834 struct if_data
*if_data
= &ifm
->ifm_data
;
836 if (if_data
->ifi_hwassist
& (IF_HWASSIST_VLAN_TAGGING
| IF_HWASSIST_VLAN_MTU
)) {
846 if (if_name
!= NULL
) CFAllocatorDeallocate(NULL
, if_name
);
847 if (buf
!= NULL
) CFAllocatorDeallocate(NULL
, buf
);
854 SCNetworkInterfacePrivateRef
855 _SCBondInterfaceCreatePrivate(CFAllocatorRef allocator
,
858 SCNetworkInterfacePrivateRef interfacePrivate
;
860 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
, NULL
);
861 if (interfacePrivate
== NULL
) {
865 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBond
;
866 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
867 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, bond_if
);
868 interfacePrivate
->builtin
= TRUE
;
869 interfacePrivate
->supportsVLAN
= __SCNetworkInterfaceSupportsVLAN(bond_if
);
870 interfacePrivate
->sort_order
= kSortBond
;
872 interfacePrivate
->localized_key
= CFSTR("bond");
873 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
875 interfacePrivate
->bond
.interfaces
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
876 // interfacePrivate->bond.mode = NULL;
877 // interfacePrivate->bond.options = NULL;
879 return interfacePrivate
;
884 SCNetworkInterfacePrivateRef
885 _SCBridgeInterfaceCreatePrivate(CFAllocatorRef allocator
,
886 CFStringRef bridge_if
)
888 SCNetworkInterfacePrivateRef interfacePrivate
;
890 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
, NULL
);
891 if (interfacePrivate
== NULL
) {
895 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBridge
;
896 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
897 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, bridge_if
);
898 interfacePrivate
->builtin
= TRUE
;
899 interfacePrivate
->supportsVLAN
= __SCNetworkInterfaceSupportsVLAN(bridge_if
);
900 interfacePrivate
->sort_order
= kSortBridge
;
902 interfacePrivate
->localized_key
= CFSTR("bridge");
903 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
905 interfacePrivate
->bridge
.interfaces
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
906 // interfacePrivate->bridge.options = NULL;
908 return interfacePrivate
;
913 SCNetworkInterfacePrivateRef
914 _SCVLANInterfaceCreatePrivate(CFAllocatorRef allocator
,
917 SCNetworkInterfacePrivateRef interfacePrivate
;
919 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
, NULL
);
920 if (interfacePrivate
== NULL
) {
924 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeVLAN
;
925 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
926 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, vlan_if
);
927 interfacePrivate
->builtin
= TRUE
;
928 interfacePrivate
->sort_order
= kSortVLAN
;
930 interfacePrivate
->localized_key
= CFSTR("vlan");
931 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
933 // interfacePrivate->vlan.interface = NULL;
934 // interfacePrivate->vlan.tag = NULL;
935 // interfacePrivate->vlan.options = NULL;
937 return interfacePrivate
;
942 #pragma mark Interface ordering
946 split_path(CFStringRef path
)
948 CFArrayRef components
;
949 CFMutableStringRef nPath
;
951 // turn '@'s into '/'s
952 nPath
= CFStringCreateMutableCopy(NULL
, 0, path
);
953 (void) CFStringFindAndReplace(nPath
,
956 CFRangeMake(0, CFStringGetLength(nPath
)),
959 // split path into components to be compared
960 components
= CFStringCreateArrayBySeparatingStrings(NULL
, nPath
, CFSTR("/"));
968 _SCNetworkInterfaceCompare(const void *val1
, const void *val2
, void *context
)
970 SCNetworkInterfacePrivateRef dev1
= (SCNetworkInterfacePrivateRef
)val1
;
971 SCNetworkInterfacePrivateRef dev2
= (SCNetworkInterfacePrivateRef
)val2
;
972 CFComparisonResult res
= kCFCompareEqualTo
;
974 /* sort by interface type */
975 if (dev1
->sort_order
!= dev2
->sort_order
) {
976 if (dev1
->sort_order
< dev2
->sort_order
) {
977 res
= kCFCompareLessThan
;
979 res
= kCFCompareGreaterThan
;
984 /* built-in interfaces sort first */
985 if (dev1
->builtin
!= dev2
->builtin
) {
987 res
= kCFCompareLessThan
;
989 res
= kCFCompareGreaterThan
;
994 /* ... and then, sort built-in interfaces by "location" */
996 if (dev1
->location
!= dev2
->location
) {
997 if (isA_CFString(dev1
->location
)) {
998 if (isA_CFString(dev2
->location
)) {
999 res
= CFStringCompare(dev1
->location
, dev2
->location
, 0);
1001 res
= kCFCompareLessThan
;
1004 res
= kCFCompareGreaterThan
;
1007 if (res
!= kCFCompareEqualTo
) {
1013 /* ... and, then sort by IOPathMatch */
1014 if ((dev1
->path
!= NULL
) && (dev2
->path
!= NULL
)) {
1015 CFArrayRef elements1
;
1016 CFArrayRef elements2
;
1022 elements1
= split_path(dev1
->path
);
1023 n1
= CFArrayGetCount(elements1
);
1025 elements2
= split_path(dev2
->path
);
1026 n2
= CFArrayGetCount(elements2
);
1028 n
= (n1
<= n2
) ? n1
: n2
;
1029 for (i
= 0; i
< n
; i
++) {
1038 e1
= CFArrayGetValueAtIndex(elements1
, i
);
1039 e2
= CFArrayGetValueAtIndex(elements2
, i
);
1041 str
= _SC_cfstring_to_cstring(e1
, NULL
, 0, kCFStringEncodingUTF8
);
1043 q1
= strtoq(str
, &end
, 16);
1044 isNum
= ((*str
!= '\0') && (*end
== '\0') && (errno
== 0));
1045 CFAllocatorDeallocate(NULL
, str
);
1048 // if e1 is a valid numeric string
1049 str
= _SC_cfstring_to_cstring(e2
, NULL
, 0, kCFStringEncodingUTF8
);
1051 q2
= strtoq(str
, &end
, 16);
1052 isNum
= ((*str
!= '\0') && (*end
== '\0') && (errno
== 0));
1053 CFAllocatorDeallocate(NULL
, str
);
1056 // if e2 is also a valid numeric string
1059 res
= kCFCompareEqualTo
;
1061 } else if (q1
< q2
) {
1062 res
= kCFCompareLessThan
;
1064 res
= kCFCompareGreaterThan
;
1070 res
= CFStringCompare(e1
, e2
, 0);
1071 if (res
!= kCFCompareEqualTo
) {
1076 if (res
== kCFCompareEqualTo
) {
1078 res
= kCFCompareLessThan
;
1079 } else if (n1
< n2
) {
1080 res
= kCFCompareGreaterThan
;
1084 CFRelease(elements1
);
1085 CFRelease(elements2
);
1087 if (res
!= kCFCompareEqualTo
) {
1092 /* ... and, then sort by BSD interface name */
1093 if ((dev1
->entity_device
!= NULL
) && (dev2
->entity_device
!= NULL
)) {
1094 res
= CFStringCompare(dev1
->entity_device
, dev2
->entity_device
, 0);
1095 if (res
!= kCFCompareEqualTo
) {
1100 /* ... and lastly, sort by BSD interface unique identifier */
1101 if ((dev1
->entity_device_unique
!= NULL
) && (dev2
->entity_device_unique
!= NULL
)) {
1102 res
= CFStringCompare(dev1
->entity_device_unique
, dev2
->entity_device_unique
, 0);
1103 // if (res != kCFCompareEqualTo) {
1113 sort_interfaces(CFMutableArrayRef all_interfaces
)
1115 int n
= CFArrayGetCount(all_interfaces
);
1121 CFArraySortValues(all_interfaces
, CFRangeMake(0, n
), _SCNetworkInterfaceCompare
, NULL
);
1128 __SCNetworkInterfaceOrder(SCNetworkInterfaceRef interface
)
1130 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
1132 return interfacePrivate
->sort_order
;
1137 #pragma mark Interface details
1141 IOCopyCFStringValue(CFTypeRef ioVal
)
1143 if (isA_CFString(ioVal
)) {
1144 return CFStringCreateCopy(NULL
, ioVal
);
1147 if (isA_CFData(ioVal
)) {
1148 return CFStringCreateWithCString(NULL
,
1149 (const char *)CFDataGetBytePtr(ioVal
),
1150 kCFStringEncodingUTF8
);
1158 IODictionaryCopyCFStringValue(CFDictionaryRef io_dict
, CFStringRef io_key
)
1162 ioVal
= CFDictionaryGetValue(io_dict
, io_key
);
1163 return IOCopyCFStringValue(ioVal
);
1168 IOStringValueHasPrefix(CFTypeRef ioVal
, CFStringRef prefix
)
1170 Boolean match
= FALSE
;
1171 CFIndex prefixLen
= CFStringGetLength(prefix
);
1172 CFStringRef str
= NULL
;
1174 if (!isA_CFString(ioVal
)) {
1175 if (isA_CFData(ioVal
)) {
1176 str
= CFStringCreateWithCStringNoCopy(NULL
,
1177 (const char *)CFDataGetBytePtr(ioVal
),
1178 kCFStringEncodingUTF8
,
1186 if ((ioVal
!= NULL
) &&
1187 (CFStringGetLength(ioVal
) >= prefixLen
) &&
1188 (CFStringCompareWithOptions(ioVal
,
1190 CFRangeMake(0, prefixLen
),
1191 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
)) {
1195 if (str
!= NULL
) CFRelease(str
);
1200 static const struct {
1201 const CFStringRef name
;
1202 const CFStringRef slot
;
1203 } slot_mappings
[] = {
1205 { CFSTR("A1") , CFSTR("1") },
1206 { CFSTR("B1") , CFSTR("2") },
1207 { CFSTR("C1") , CFSTR("3") },
1209 // Blue&White G3, Yikes G4
1210 { CFSTR("J12"), CFSTR("1") },
1211 { CFSTR("J11"), CFSTR("2") },
1212 { CFSTR("J10"), CFSTR("3") },
1213 { CFSTR("J9"), CFSTR("4") },
1216 { CFSTR("A") , CFSTR("1") },
1217 { CFSTR("B") , CFSTR("2") },
1218 { CFSTR("C") , CFSTR("3") },
1219 { CFSTR("D") , CFSTR("4") },
1221 // Digital Audio G4 (and later models)
1222 { CFSTR("1") , CFSTR("1") },
1223 { CFSTR("2") , CFSTR("2") },
1224 { CFSTR("3") , CFSTR("3") },
1225 { CFSTR("4") , CFSTR("4") },
1226 { CFSTR("5") , CFSTR("5") }
1230 static const CFStringRef slot_prefixes
[] = {
1231 CFSTR("thunderbolt slot "),
1238 pci_slot(io_registry_entry_t interface
, CFTypeRef
*pci_slot_name
)
1241 io_registry_entry_t parent
;
1242 CFMutableStringRef slot
;
1243 CFTypeRef slot_name
;
1246 if (pci_slot_name
!= NULL
) *pci_slot_name
= NULL
;
1248 slot_name
= IORegistryEntryCreateCFProperty(interface
, CFSTR("AAPL,slot-name"), NULL
, 0);
1249 if (slot_name
!= NULL
) {
1252 slot
= CFStringCreateMutable(NULL
, 0);
1253 if (isA_CFString(slot_name
)) {
1254 if (pci_slot_name
!= NULL
) *pci_slot_name
= CFStringCreateCopy(NULL
, slot_name
);
1255 CFStringAppend(slot
, slot_name
);
1256 } else if (isA_CFData(slot_name
)) {
1257 if (pci_slot_name
!= NULL
) *pci_slot_name
= CFDataCreateCopy(NULL
, slot_name
);
1258 CFStringAppendCString(slot
,
1259 (const char *)CFDataGetBytePtr(slot_name
),
1260 kCFStringEncodingUTF8
);
1263 for (i
= 0; i
< sizeof(slot_prefixes
)/sizeof(slot_prefixes
[0]); i
++) {
1266 len
= CFStringGetLength(slot_prefixes
[i
]);
1267 if (CFStringGetLength(slot
) > len
) {
1268 (void) CFStringFindAndReplace(slot
,
1271 CFRangeMake(0, len
),
1272 kCFCompareCaseInsensitive
|kCFCompareAnchored
);
1276 for (i
= 0; i
< sizeof(slot_mappings
)/sizeof(slot_mappings
[0]); i
++) {
1277 if (CFStringCompare(slot
,
1278 slot_mappings
[i
].name
,
1279 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
1281 slot
= (CFMutableStringRef
)CFRetain(slot_mappings
[i
].slot
);
1286 CFRelease(slot_name
);
1289 kr
= IORegistryEntryGetParentEntry(interface
, kIOServicePlane
, &parent
);
1291 case kIOReturnSuccess
: {
1292 CFTypeRef parent_pci_slot_name
= NULL
;
1293 CFStringRef parent_slot
;
1295 parent_slot
= pci_slot(parent
, &parent_pci_slot_name
);
1296 if (parent_slot
!= NULL
) {
1297 if (slot
!= NULL
) CFRelease(slot
);
1298 slot
= (CFMutableStringRef
)parent_slot
;
1300 if (pci_slot_name
!= NULL
) {
1301 if (*pci_slot_name
!= NULL
) CFRelease(*pci_slot_name
);
1302 *pci_slot_name
= parent_pci_slot_name
;
1304 CFRelease(parent_pci_slot_name
);
1308 IOObjectRelease(parent
);
1311 case kIOReturnNoDevice
:
1312 // if we have hit the root node
1315 SCLog(TRUE
, LOG_DEBUG
, CFSTR("pci_slot IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr
);
1323 static CFComparisonResult
1324 compare_bsdNames(const void *val1
, const void *val2
, void *context
)
1326 CFStringRef bsd1
= (CFStringRef
)val1
;
1327 CFStringRef bsd2
= (CFStringRef
)val2
;
1329 return CFStringCompare(bsd1
, bsd2
, 0);
1334 pci_port(CFTypeRef slot_name
, int ift
, CFStringRef bsdName
)
1337 CFStringRef port_name
= NULL
;
1338 CFMutableArrayRef port_names
;
1341 CFStringRef match_keys
[2];
1342 CFTypeRef match_vals
[2];
1343 CFDictionaryRef match_dict
;
1344 CFDictionaryRef matching
;
1345 io_registry_entry_t slot
;
1346 io_iterator_t slot_iterator
= MACH_PORT_NULL
;
1348 match_keys
[0] = CFSTR("AAPL,slot-name");
1349 match_vals
[0] = slot_name
;
1351 match_dict
= CFDictionaryCreate(NULL
,
1352 (const void **)match_keys
,
1353 (const void **)match_vals
,
1355 &kCFTypeDictionaryKeyCallBacks
,
1356 &kCFTypeDictionaryValueCallBacks
);
1358 match_keys
[0] = CFSTR(kIOProviderClassKey
);
1359 match_vals
[0] = CFSTR("IOPCIDevice");
1361 match_keys
[1] = CFSTR(kIOPropertyMatchKey
);
1362 match_vals
[1] = match_dict
;
1364 // note: the "matching" dictionary will be consumed by the following
1365 matching
= CFDictionaryCreate(NULL
,
1366 (const void **)match_keys
,
1367 (const void **)match_vals
,
1368 sizeof(match_keys
)/sizeof(match_keys
[0]),
1369 &kCFTypeDictionaryKeyCallBacks
,
1370 &kCFTypeDictionaryValueCallBacks
);
1371 CFRelease(match_dict
);
1373 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &slot_iterator
);
1374 if (kr
!= kIOReturnSuccess
) {
1375 SCLog(TRUE
, LOG_DEBUG
, CFSTR("pci_port IOServiceGetMatchingServices() failed, kr = 0x%x"), kr
);
1376 return MACH_PORT_NULL
;
1379 port_names
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1381 while ((slot
= IOIteratorNext(slot_iterator
)) != MACH_PORT_NULL
) {
1382 io_registry_entry_t child
;
1383 io_iterator_t child_iterator
= MACH_PORT_NULL
;
1385 kr
= IORegistryEntryCreateIterator(slot
,
1387 kIORegistryIterateRecursively
,
1389 if (kr
!= kIOReturnSuccess
) {
1390 SCLog(TRUE
, LOG_DEBUG
, CFSTR("pci_port IORegistryEntryCreateIterator() failed, kr = 0x%x"), kr
);
1391 CFRelease(port_names
);
1392 return MACH_PORT_NULL
;
1395 while ((child
= IOIteratorNext(child_iterator
)) != MACH_PORT_NULL
) {
1396 if (IOObjectConformsTo(child
, kIONetworkInterfaceClass
)) {
1397 CFNumberRef child_if_type
;
1398 int child_ift
= ift
;
1400 child_if_type
= IORegistryEntryCreateCFProperty(child
,
1401 CFSTR(kIOInterfaceType
),
1404 if (child_if_type
!= NULL
) {
1405 if (!isA_CFNumber(child_if_type
) ||
1406 !CFNumberGetValue(child_if_type
, kCFNumberIntType
, &child_ift
)) {
1407 // assume that it's a match
1410 CFRelease(child_if_type
);
1413 if (ift
== child_ift
) {
1414 CFStringRef if_bsdName
;
1416 if_bsdName
= IORegistryEntryCreateCFProperty(child
,
1417 CFSTR(kIOBSDNameKey
),
1420 if (if_bsdName
!= NULL
) {
1421 CFArrayAppendValue(port_names
, if_bsdName
);
1422 CFRelease(if_bsdName
);
1426 IOObjectRelease(child
);
1428 IOObjectRelease(child_iterator
);
1429 IOObjectRelease(slot
);
1431 IOObjectRelease(slot_iterator
);
1433 n
= CFArrayGetCount(port_names
);
1435 CFArraySortValues(port_names
, CFRangeMake(0, n
), compare_bsdNames
, NULL
);
1436 n
= CFArrayGetFirstIndexOfValue(port_names
, CFRangeMake(0, n
), bsdName
);
1437 if (n
!= kCFNotFound
) {
1438 port_name
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%d"), n
+ 1);
1442 CFRelease(port_names
);
1448 pci_slot_info(io_registry_entry_t interface
, int ift
, CFStringRef
*slot_name
, CFStringRef
*port_name
)
1450 CFStringRef bsd_name
;
1452 CFTypeRef pci_slot_name
;
1457 bsd_name
= IORegistryEntryCreateCFProperty(interface
, CFSTR(kIOBSDNameKey
), NULL
, 0);
1458 if (bsd_name
== NULL
) {
1462 *slot_name
= pci_slot(interface
, &pci_slot_name
);
1463 if (*slot_name
!= NULL
) {
1464 if (pci_slot_name
!= NULL
) {
1465 *port_name
= pci_port(pci_slot_name
, ift
, bsd_name
);
1466 CFRelease(pci_slot_name
);
1471 CFRelease(bsd_name
);
1477 isBuiltin(io_registry_entry_t interface
)
1481 slot
= pci_slot(interface
, NULL
);
1483 // interfaces which have a "slot" are not built-in
1493 isBluetoothBuiltin(Boolean
*haveController
)
1495 Boolean builtin
= FALSE
;
1496 io_object_t hciController
;
1497 io_iterator_t iter
= MACH_PORT_NULL
;
1500 kr
= IOServiceGetMatchingServices(masterPort
,
1501 IOServiceMatching("IOBluetoothHCIController"),
1503 if ((kr
!= kIOReturnSuccess
) || (iter
== MACH_PORT_NULL
)) {
1504 if (kr
!= kIOReturnSuccess
) {
1505 SCLog(TRUE
, LOG_DEBUG
, CFSTR("isBluetoothBuiltin IOServiceGetMatchingServices() failed, kr = 0x%x"), kr
);
1507 *haveController
= FALSE
;
1510 *haveController
= TRUE
;
1512 hciController
= IOIteratorNext(iter
);
1513 IOObjectRelease(iter
);
1514 if(hciController
!= MACH_PORT_NULL
) {
1515 CFNumberRef idVendor
;
1517 idVendor
= IORegistryEntryCreateCFProperty(hciController
, CFSTR(kUSBVendorID
), NULL
, 0);
1518 if (idVendor
!= NULL
) {
1521 if (isA_CFNumber(idVendor
) &&
1522 CFNumberGetValue(idVendor
, kCFNumberIntType
, &idVendorVal
) &&
1523 (idVendorVal
== kIOUSBVendorIDAppleComputer
)) {
1527 CFRelease(idVendor
);
1530 IOObjectRelease(hciController
);
1538 isThunderbolt(io_registry_entry_t interface
)
1542 val
= IORegistryEntrySearchCFProperty(interface
,
1544 CFSTR(kPCIThunderboltString
),
1546 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1557 processUSBInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1558 io_registry_entry_t interface
,
1559 CFDictionaryRef interface_dict
,
1560 io_registry_entry_t controller
,
1561 CFDictionaryRef controller_dict
,
1562 io_registry_entry_t bus
,
1563 CFDictionaryRef bus_dict
)
1566 interfacePrivate
->usb
.name
= IORegistryEntrySearchCFProperty(interface
,
1568 CFSTR(kUSBProductString
),
1570 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1571 interfacePrivate
->usb
.vid
= IORegistryEntrySearchCFProperty(interface
,
1573 CFSTR(kUSBVendorID
),
1575 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1576 interfacePrivate
->usb
.pid
= IORegistryEntrySearchCFProperty(interface
,
1578 CFSTR(kUSBProductID
),
1580 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1587 update_interface_name(SCNetworkInterfacePrivateRef interfacePrivate
,
1588 io_registry_entry_t interface
,
1591 Boolean updated
= FALSE
;
1594 // check if a "Product Name" has been provided
1595 val
= IORegistryEntrySearchCFProperty(interface
,
1597 CFSTR(kIOPropertyProductNameKey
),
1599 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1600 if ((val
== NULL
) && useUSBInfo
&& (interfacePrivate
->usb
.name
!= NULL
)) {
1601 // else, use "USB Product Name" if available
1602 val
= CFRetain(interfacePrivate
->usb
.name
);
1605 CFStringRef productName
;
1607 productName
= IOCopyCFStringValue(val
);
1610 if (productName
!= NULL
) {
1611 if (CFStringGetLength(productName
) > 0) {
1612 // if we have a [somewhat reasonable?] product name
1613 if (interfacePrivate
->name
!= NULL
) {
1614 CFRelease(interfacePrivate
->name
);
1616 interfacePrivate
->name
= CFRetain(productName
);
1617 if (interfacePrivate
->localized_name
!= NULL
) {
1618 CFRelease(interfacePrivate
->localized_name
);
1620 interfacePrivate
->localized_name
= copy_interface_string(bundle
, productName
, TRUE
);
1625 CFRelease(productName
);
1634 #pragma mark Interface enumeration
1637 typedef Boolean (*processInterface
)(SCNetworkInterfacePrivateRef interfacePrivate
,
1638 io_registry_entry_t interface
,
1639 CFDictionaryRef interface_dict
,
1640 io_registry_entry_t controller
,
1641 CFDictionaryRef controller_dict
,
1642 io_registry_entry_t bus
,
1643 CFDictionaryRef bus_dict
);
1647 merge_override(SCNetworkInterfacePrivateRef interfacePrivate
,
1648 io_registry_entry_t interface
,
1649 CFStringRef override
)
1654 key
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("Device%@Overrides"), override
);
1655 val
= IORegistryEntrySearchCFProperty(interface
,
1659 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1662 if (isA_CFDictionary(val
)) {
1663 if (interfacePrivate
->overrides
== NULL
) {
1664 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
1666 &kCFTypeDictionaryKeyCallBacks
,
1667 &kCFTypeDictionaryValueCallBacks
);
1669 CFDictionarySetValue(interfacePrivate
->overrides
, override
, val
);
1679 processNetworkInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1680 io_registry_entry_t interface
,
1681 CFDictionaryRef interface_dict
,
1682 io_registry_entry_t controller
,
1683 CFDictionaryRef controller_dict
,
1684 io_registry_entry_t bus
,
1685 CFDictionaryRef bus_dict
)
1695 num
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceType
));
1696 if (isA_CFNumber(num
) &&
1697 CFNumberGetValue(num
, kCFNumberIntType
, &ift
)) {
1698 interfacePrivate
->type
= CFRetain(num
);
1700 SCLog(TRUE
, LOG_DEBUG
, CFSTR("processNetworkInterface() failed, no interface type"));
1708 if ((IOObjectConformsTo(controller
, "IO80211Controller")) ||
1709 (IOObjectConformsTo(controller
, "AirPortPCI" )) ||
1710 (IOObjectConformsTo(controller
, "AirPortDriver" ))) {
1711 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
1712 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1713 interfacePrivate
->sort_order
= kSortAirPort
;
1714 } else if (IOObjectConformsTo(controller
, "IOBluetoothBNEPDriver")) {
1715 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1716 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1717 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
1718 } else if (IOObjectConformsTo(controller
, "AppleUSBEthernetHost")) {
1719 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1720 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1721 interfacePrivate
->sort_order
= kSortTethered
;
1722 } else if (IOObjectConformsTo(controller
, "AppleUSBCDCECMData")) {
1723 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1724 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1725 interfacePrivate
->sort_order
= kSortWWANEthernet
;
1728 if (interfacePrivate
->interface_type
== NULL
) {
1729 val
= IORegistryEntrySearchCFProperty(interface
,
1731 CFSTR(kIOUserEthernetInterfaceRoleKey
),
1733 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1735 if (isA_CFString(val
)) {
1736 if (CFEqual(val
, CFSTR("Bluetooth PAN"))) {
1737 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1738 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1739 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
1740 } else if (CFEqual(val
, CFSTR("Bluetooth PAN-NAP"))) {
1741 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1742 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1743 interfacePrivate
->sort_order
= kSortBluetoothPAN_NAP
;
1744 } else if (CFEqual(val
, CFSTR("Bluetooth P2P"))) {
1745 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1746 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1747 interfacePrivate
->sort_order
= kSortBluetoothPAN_U
;
1755 if (interfacePrivate
->interface_type
== NULL
) {
1756 str
= IODictionaryCopyCFStringValue(bus_dict
, CFSTR("name"));
1758 if (CFEqual(str
, CFSTR("radio"))) {
1759 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
; // ??
1760 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1761 interfacePrivate
->sort_order
= kSortOtherWireless
;
1768 if (interfacePrivate
->interface_type
== NULL
) {
1769 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1770 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1771 interfacePrivate
->sort_order
= kSortEthernet
;
1773 // BOND support only enabled for ethernet devices
1774 interfacePrivate
->supportsBond
= TRUE
;
1777 // enable Bridge support
1778 interfacePrivate
->supportsBridge
= TRUE
;
1781 val
= isA_CFBoolean(CFDictionaryGetValue(interface_dict
, CFSTR(kIOBuiltin
)));
1783 val
= isA_CFBoolean(CFDictionaryGetValue(interface_dict
, CFSTR(kIOPrimaryInterface
)));
1786 interfacePrivate
->builtin
= CFBooleanGetValue(val
);
1788 interfacePrivate
->builtin
= isBuiltin(interface
);
1791 if (!interfacePrivate
->builtin
&&
1792 CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
)) {
1793 // always treat AirPort interfaces as built-in
1794 interfacePrivate
->builtin
= TRUE
;
1798 interfacePrivate
->location
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOLocation
));
1801 num
= CFDictionaryGetValue(controller_dict
, CFSTR(kIOFeatures
));
1802 if (isA_CFNumber(num
) &&
1803 CFNumberGetValue(num
, kCFNumberIntType
, & iVal
)) {
1804 if (iVal
& (kIONetworkFeatureHardwareVlan
| kIONetworkFeatureSoftwareVlan
)) {
1805 interfacePrivate
->supportsVLAN
= TRUE
;
1810 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
)) {
1811 interfacePrivate
->localized_key
= CFSTR("airport");
1812 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_GN
) {
1813 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-gn");
1814 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_NAP
) {
1815 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-nap");
1816 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_U
) {
1817 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-u");
1818 } else if (interfacePrivate
->sort_order
== kSortOtherWireless
) {
1819 interfacePrivate
->localized_key
= CFSTR("wireless");
1820 interfacePrivate
->localized_arg1
= CFRetain(CFSTR("")); // ??
1821 } else if (interfacePrivate
->builtin
) {
1822 if ((interfacePrivate
->location
== NULL
) ||
1823 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1824 interfacePrivate
->localized_key
= CFSTR("ether");
1826 interfacePrivate
->localized_key
= CFSTR("multiether");
1827 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->location
);
1830 CFStringRef provider
;
1832 // check provider class
1833 provider
= IORegistryEntrySearchCFProperty(interface
,
1835 CFSTR(kIOProviderClassKey
),
1837 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1838 if (provider
!= NULL
) {
1839 if (CFEqual(provider
, CFSTR("IOPCIDevice"))) {
1840 CFStringRef port_name
;
1841 CFStringRef slot_name
;
1843 // set interface "name"
1844 if (!update_interface_name(interfacePrivate
, interface
, FALSE
) &&
1845 pci_slot_info(interface
, ift
, &slot_name
, &port_name
)) {
1846 if (isThunderbolt(interface
)) {
1847 if (port_name
== NULL
) {
1848 interfacePrivate
->localized_key
= CFSTR("thunderbolt-ether");
1849 interfacePrivate
->localized_arg1
= slot_name
;
1851 interfacePrivate
->localized_key
= CFSTR("thunderbolt-multiether");
1852 interfacePrivate
->localized_arg1
= slot_name
;
1853 interfacePrivate
->localized_arg2
= port_name
;
1857 if (port_name
== NULL
) {
1858 interfacePrivate
->localized_key
= CFSTR("pci-ether");
1859 interfacePrivate
->localized_arg1
= slot_name
;
1861 interfacePrivate
->localized_key
= CFSTR("pci-multiether");
1862 interfacePrivate
->localized_arg1
= slot_name
;
1863 interfacePrivate
->localized_arg2
= port_name
;
1867 } else if (CFEqual(provider
, CFSTR("IOUSBDevice")) ||
1868 CFEqual(provider
, CFSTR("IOUSBInterface"))) {
1869 // get USB info (if available)
1870 processUSBInterface(interfacePrivate
,
1878 // set interface "name"
1879 if (!update_interface_name(interfacePrivate
, interface
, TRUE
)) {
1880 interfacePrivate
->localized_key
= CFSTR("usb-ether");
1881 interfacePrivate
->localized_arg1
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOBSDNameKey
));
1884 CFRelease(provider
);
1887 if (interfacePrivate
->localized_key
== NULL
) {
1888 // if no provider, not a PCI device, or no slot information
1889 interfacePrivate
->localized_key
= CFSTR("generic-ether");
1890 interfacePrivate
->localized_arg1
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOBSDNameKey
));
1897 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeFireWire
;
1900 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeFireWire
;
1903 interfacePrivate
->builtin
= isBuiltin(interface
);
1906 interfacePrivate
->sort_order
= kSortFireWire
;
1909 if (interfacePrivate
->builtin
) {
1910 interfacePrivate
->localized_key
= CFSTR("firewire");
1912 CFStringRef port_name
;
1913 CFStringRef slot_name
;
1915 // set interface "name"
1916 if (!update_interface_name(interfacePrivate
, interface
, FALSE
) &&
1917 pci_slot_info(interface
, ift
, &slot_name
, &port_name
)) {
1918 if (isThunderbolt(interface
)) {
1919 if (port_name
== NULL
) {
1920 interfacePrivate
->localized_key
= CFSTR("thunderbolt-firewire");
1921 interfacePrivate
->localized_arg1
= slot_name
;
1923 interfacePrivate
->localized_key
= CFSTR("thunderbolt-multifirewire");
1924 interfacePrivate
->localized_arg1
= slot_name
;
1925 interfacePrivate
->localized_arg2
= port_name
;
1928 if (port_name
== NULL
) {
1929 interfacePrivate
->localized_key
= CFSTR("pci-firewire");
1930 interfacePrivate
->localized_arg1
= slot_name
;
1932 interfacePrivate
->localized_key
= CFSTR("pci-multifirewire");
1933 interfacePrivate
->localized_arg1
= slot_name
;
1934 interfacePrivate
->localized_arg2
= port_name
;
1942 SCLog(TRUE
, LOG_DEBUG
, CFSTR("processNetworkInterface() failed, unknown interface type = %d"), ift
);
1947 interfacePrivate
->entity_device
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOBSDNameKey
));
1949 // Hardware (MAC) address
1950 data
= CFDictionaryGetValue(controller_dict
, CFSTR(kIOMACAddress
));
1951 if (isA_CFData(data
)) {
1952 interfacePrivate
->address
= CFRetain(data
);
1956 num
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceUnit
));
1957 if (isA_CFNumber(num
) &&
1958 CFNumberGetValue(num
, kCFNumberIntType
, & iVal
)) {
1959 interfacePrivate
->unit
= CFRetain(num
);
1962 // configuration [PPP] template override (now deprecated, use NetworkConfigurationOverrides)
1963 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypePPP
);
1970 set_connection_script(SCNetworkInterfacePrivateRef interfacePrivate
, CFStringRef script
)
1972 CFDictionaryRef dict
;
1973 CFMutableDictionaryRef newDict
;
1975 if (interfacePrivate
->overrides
== NULL
) {
1976 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
1978 &kCFTypeDictionaryKeyCallBacks
,
1979 &kCFTypeDictionaryValueCallBacks
);
1982 dict
= CFDictionaryGetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
1984 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
1986 newDict
= CFDictionaryCreateMutable(NULL
,
1988 &kCFTypeDictionaryKeyCallBacks
,
1989 &kCFTypeDictionaryValueCallBacks
);
1991 if (script
!= NULL
) {
1992 CFDictionarySetValue(newDict
, kSCPropNetModemConnectionScript
, script
);
1994 CFDictionaryRemoveValue(newDict
, kSCPropNetModemConnectionScript
);
1996 if (CFDictionaryGetCount(newDict
) > 0) {
1997 CFDictionarySetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
, newDict
);
1999 CFDictionaryRemoveValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
2003 if (CFDictionaryGetCount(interfacePrivate
->overrides
) == 0) {
2004 CFRelease(interfacePrivate
->overrides
);
2005 interfacePrivate
->overrides
= NULL
;
2012 is_valid_connection_script(CFStringRef script
)
2014 char ccl
[MAXPATHLEN
];
2015 char path
[MAXPATHLEN
];
2016 NSSearchPathEnumerationState state
;
2018 (void) _SC_cfstring_to_cstring(script
,
2021 kCFStringEncodingUTF8
);
2023 state
= NSStartSearchPathEnumeration(NSLibraryDirectory
,
2024 NSLocalDomainMask
|NSSystemDomainMask
);
2025 while ((state
= NSGetNextSearchPathEnumeration(state
, path
))) {
2027 struct stat statBuf
;
2029 if (ccl
[0] == '/') {
2030 path
[0] = '\0'; // if modemCCL is a full path
2032 strlcat(path
, "/Modem Scripts/", sizeof(path
));
2034 strlcat(path
, ccl
, sizeof(path
));
2036 if (stat(path
, &statBuf
) != 0) {
2037 if (errno
== ENOENT
) {
2041 SCLog(TRUE
, LOG_DEBUG
,
2042 CFSTR("processSerialInterface stat() failed: %s"),
2046 if (S_ISREG(statBuf
.st_mode
)) {
2047 // if we have a valid CCL script
2051 #define BUNDLE_EXT ".ccl"
2052 #define BUNDLE_EXT_LEN sizeof(BUNDLE_EXT) - 1
2057 if ((n
<= BUNDLE_EXT_LEN
) ||
2058 (strstr(&path
[n
- BUNDLE_EXT_LEN
], BUNDLE_EXT
) == NULL
)) {
2059 strlcat(path
, BUNDLE_EXT
, sizeof(path
));
2060 if (stat(path
, &statBuf
) != 0) {
2061 if (errno
== ENOENT
) {
2065 SCLog(TRUE
, LOG_DEBUG
,
2066 CFSTR("processSerialInterface stat() failed: %s"),
2071 if (S_ISDIR(statBuf
.st_mode
)) {
2072 // if we have a valid CCL bundle
2082 processSerialInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
2083 io_registry_entry_t interface
,
2084 CFDictionaryRef interface_dict
,
2085 io_registry_entry_t controller
,
2086 CFDictionaryRef controller_dict
,
2087 io_registry_entry_t bus
,
2088 CFDictionaryRef bus_dict
)
2090 CFStringRef base
= NULL
;
2092 Boolean isModem
= FALSE
;
2093 Boolean isWWAN
= FALSE
;
2094 CFStringRef modemCCL
= NULL
;
2099 val
= IORegistryEntrySearchCFProperty(interface
,
2101 kSCNetworkInterfaceHiddenPortKey
,
2103 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2106 return FALSE
; // if this interface should not be exposed
2109 // check if initializing
2110 val
= IORegistryEntrySearchCFProperty(interface
,
2112 kSCNetworkInterfaceInitializingKey
,
2114 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2116 Boolean initializing
;
2118 initializing
= isA_CFBoolean(val
) && CFBooleanGetValue(val
);
2121 return FALSE
; // if this interface is still initializing
2126 val
= IORegistryEntrySearchCFProperty(interface
,
2130 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2132 isWWAN
= isA_CFBoolean(val
) && CFBooleanGetValue(val
);
2137 interfacePrivate
->entity_device
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOTTYDeviceKey
));
2138 if (interfacePrivate
->entity_device
== NULL
) {
2142 base
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOTTYBaseNameKey
));
2144 base
= CFRetain(interfacePrivate
->entity_device
);
2150 * Exclude ports named "irda" because otherwise the IrDA ports on the
2151 * original iMac (rev's A through D) show up as serial ports. Given
2152 * that only the rev A actually had an IrDA port, and Mac OS X doesn't
2153 * even support it, these ports definitely shouldn't be listed.
2155 if (CFStringCompare(base
,
2157 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
2161 if (IOStringValueHasPrefix(base
, CFSTR("bluetooth"))) {
2162 Boolean haveController
= FALSE
;
2165 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBluetooth
;
2166 interfacePrivate
->sort_order
= kSortBluetooth
;
2167 interfacePrivate
->builtin
= isBluetoothBuiltin(&haveController
);
2168 if (!haveController
) {
2169 // if device with no controller present
2172 } else if (IOStringValueHasPrefix(base
, CFSTR("irda-ircomm"))) {
2174 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIrDA
;
2175 interfacePrivate
->sort_order
= kSortIrDA
;
2176 } else if (isWWAN
) {
2178 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeWWAN
;
2179 interfacePrivate
->sort_order
= kSortWWAN
;
2182 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeModem
;
2183 interfacePrivate
->sort_order
= kSortModem
;
2186 val
= IORegistryEntrySearchCFProperty(interface
,
2188 CFSTR(kIODeviceSupportsHoldKey
),
2190 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2194 if (isA_CFNumber(val
) &&
2195 CFNumberGetValue(val
, kCFNumberSInt32Type
, &v92
)) {
2196 interfacePrivate
->modemIsV92
= (v92
== 1);
2203 interfacePrivate
->entity_type
= kSCEntNetModem
;
2205 // Entity (Hardware)
2206 ift
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOSerialBSDTypeKey
));
2207 if (!isA_CFString(ift
)) {
2211 if (CFEqual(ift
, CFSTR(kIOSerialBSDModemType
))) {
2215 if (CFEqual(base
, CFSTR("modem"))) {
2216 interfacePrivate
->builtin
= TRUE
;
2217 interfacePrivate
->sort_order
= kSortInternalModem
;
2218 } else if (CFEqual(base
, CFSTR("usbmodem"))) {
2219 interfacePrivate
->sort_order
= kSortUSBModem
;
2221 } else if (CFEqual(ift
, CFSTR(kIOSerialBSDRS232Type
))) {
2223 interfacePrivate
->sort_order
= kSortSerialPort
;
2228 // configuration [PPP] template override (now deprecated, use NetworkConfigurationOverrides)
2229 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypePPP
);
2231 // configuration [Modem] template override (now deprecated, use NetworkConfigurationOverrides)
2232 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypeModem
);
2234 // look for modem CCL, unique identifier
2235 if (interfacePrivate
->overrides
!= NULL
) {
2236 val
= CFDictionaryGetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
2238 CFStringRef uniqueID
;
2240 modemCCL
= CFDictionaryGetValue(val
, kSCPropNetModemConnectionScript
);
2241 modemCCL
= isA_CFString(modemCCL
);
2243 uniqueID
= CFDictionaryGetValue(val
, CFSTR("UniqueIdentifier"));
2244 uniqueID
= isA_CFString(uniqueID
);
2245 if (uniqueID
!= NULL
) {
2246 // retain the device's base name and the unique id
2247 CFRelease(interfacePrivate
->entity_device
);
2248 interfacePrivate
->entity_device
= CFRetain(base
);
2249 interfacePrivate
->entity_device_unique
= CFStringCreateCopy(NULL
, uniqueID
);
2254 // if not part of the NetworkConfigurationOverrides/DeviceModemOverrides, look
2255 // a bit harder for the modem CCL
2256 if (modemCCL
== NULL
) {
2257 val
= IORegistryEntrySearchCFProperty(interface
,
2261 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2263 modemCCL
= IOCopyCFStringValue(val
);
2264 if (modemCCL
!= NULL
) {
2265 set_connection_script(interfacePrivate
, modemCCL
);
2266 CFRelease(modemCCL
);
2274 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIrDA
)) {
2275 interfacePrivate
->localized_key
= CFSTR("irda");
2276 } else if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBluetooth
)) {
2277 interfacePrivate
->localized_key
= CFSTR("bluetooth");
2279 CFStringRef localized
= NULL
;
2280 CFStringRef name
= NULL
;
2281 CFMutableStringRef port
;
2283 port
= CFStringCreateMutableCopy(NULL
, 0, base
);
2284 CFStringLowercase(port
, NULL
);
2287 CFStringAppend(port
, CFSTR("-port"));
2290 // set non-localized name
2291 if (bundle
!= NULL
) {
2292 name
= copy_interface_string(bundle
, port
, FALSE
);
2295 if (!CFEqual(port
, name
)) {
2296 // if [English] localization available
2297 interfacePrivate
->name
= name
;
2299 // if no [English] localization available, use TTY base name
2301 interfacePrivate
->name
= CFStringCreateCopy(NULL
, base
);
2304 interfacePrivate
->name
= CFStringCreateCopy(NULL
, base
);
2307 // set localized name
2308 if (bundle
!= NULL
) {
2309 localized
= copy_interface_string(bundle
, port
, TRUE
);
2311 if (localized
!= NULL
) {
2312 if (!CFEqual(port
, localized
)) {
2313 // if localization available
2314 interfacePrivate
->localized_name
= localized
;
2316 // if no localization available, use TTY base name
2317 CFRelease(localized
);
2318 interfacePrivate
->localized_name
= CFStringCreateCopy(NULL
, base
);
2321 interfacePrivate
->localized_name
= CFStringCreateCopy(NULL
, base
);
2324 if (!isModem
|| !CFEqual(base
, CFSTR("modem"))) {
2325 // get USB info (if available)
2326 processUSBInterface(interfacePrivate
,
2334 // set interface "name"
2335 if (update_interface_name(interfacePrivate
, interface
, TRUE
)) {
2336 // if "ModemCCL" not provided, also check if the product/interface
2337 // name matches a CCL script
2338 if ((modemCCL
== NULL
) &&
2339 is_valid_connection_script(interfacePrivate
->name
)) {
2340 set_connection_script(interfacePrivate
, interfacePrivate
->name
);
2352 if (!ok
&& (interfacePrivate
->entity_device
!= NULL
)) {
2353 CFRelease(interfacePrivate
->entity_device
);
2354 interfacePrivate
->entity_device
= NULL
;
2356 if (base
!= NULL
) CFRelease(base
);
2362 static SCNetworkInterfaceRef
2363 createInterface(io_registry_entry_t interface
, processInterface func
)
2365 io_registry_entry_t bus
= MACH_PORT_NULL
;
2366 CFMutableDictionaryRef bus_dict
= NULL
;
2367 io_registry_entry_t controller
= MACH_PORT_NULL
;
2368 CFMutableDictionaryRef controller_dict
= NULL
;
2369 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
2370 CFMutableDictionaryRef interface_dict
= NULL
;
2375 kr
= IORegistryEntryGetPath(interface
, kIOServicePlane
, path
);
2376 if (kr
!= kIOReturnSuccess
) {
2377 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryGetPath() failed, kr = 0x%x"), kr
);
2381 kr
= IORegistryEntryCreateCFProperties(interface
, &interface_dict
, NULL
, kNilOptions
);
2382 if (kr
!= kIOReturnSuccess
) {
2383 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryCreateCFProperties() failed, kr = 0x%x"), kr
);
2387 /* get the controller node */
2388 kr
= IORegistryEntryGetParentEntry(interface
, kIOServicePlane
, &controller
);
2389 if (kr
!= KERN_SUCCESS
) {
2390 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr
);
2394 /* get the dictionary associated with the node */
2395 kr
= IORegistryEntryCreateCFProperties(controller
, &controller_dict
, NULL
, kNilOptions
);
2396 if (kr
!= KERN_SUCCESS
) {
2397 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryCreateCFProperties() failed, kr = 0x%x"), kr
);
2401 /* get the bus node */
2402 kr
= IORegistryEntryGetParentEntry(controller
, kIOServicePlane
, &bus
);
2403 if (kr
!= KERN_SUCCESS
) {
2404 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr
);
2408 /* get the dictionary associated with the node */
2409 kr
= IORegistryEntryCreateCFProperties(bus
, &bus_dict
, NULL
, kNilOptions
);
2410 if (kr
!= KERN_SUCCESS
) {
2411 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryCreateCFProperties() failed, kr = 0x%x"), kr
);
2415 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
, path
);
2417 // configuration [PPP, Modem, DNS, IPv4, IPv6, Proxies, SMB] template overrides
2418 val
= IORegistryEntrySearchCFProperty(interface
,
2420 kSCNetworkInterfaceNetworkConfigurationOverridesKey
,
2422 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2424 if (isA_CFDictionary(val
)) {
2425 interfacePrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, val
);
2430 if ((*func
)(interfacePrivate
, interface
, interface_dict
, controller
, controller_dict
, bus
, bus_dict
)) {
2431 /* get user-notification / auto-configuration preference */
2432 val
= IORegistryEntrySearchCFProperty(interface
,
2434 kSCNetworkInterfaceConfigurationActionKey
,
2436 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2438 if (isA_CFString(val
)) {
2439 interfacePrivate
->configurationAction
= CFRetain(val
);
2444 /* get HiddenConfiguration preference */
2445 val
= IORegistryEntrySearchCFProperty(interface
,
2447 kSCNetworkInterfaceHiddenConfigurationKey
,
2449 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2451 interfacePrivate
->hidden
= TRUE
;
2455 CFRelease(interfacePrivate
);
2456 interfacePrivate
= NULL
;
2461 if (interface_dict
!= NULL
) CFRelease(interface_dict
);
2463 if (controller
!= MACH_PORT_NULL
) IOObjectRelease(controller
);
2464 if (controller_dict
!= NULL
) CFRelease(controller_dict
);
2466 if (bus
!= MACH_PORT_NULL
) IOObjectRelease(bus
);
2467 if (bus_dict
!= NULL
) CFRelease(bus_dict
);
2469 return (SCNetworkInterfaceRef
)interfacePrivate
;
2474 findMatchingInterfaces(CFDictionaryRef matching
, processInterface func
)
2476 CFMutableArrayRef interfaces
;
2477 io_registry_entry_t interface
;
2479 io_iterator_t iterator
= MACH_PORT_NULL
;
2482 * A reference to the "matching" dictionary will be consumed by the
2483 * the call to IOServiceGetMatchingServices so we bump up the retain
2488 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &iterator
);
2489 if (kr
!= kIOReturnSuccess
) {
2490 SCLog(TRUE
, LOG_DEBUG
, CFSTR("findMatchingInterfaces IOServiceGetMatchingServices() failed, kr = 0x%x"), kr
);
2494 interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2496 while ((interface
= IOIteratorNext(iterator
)) != MACH_PORT_NULL
) {
2497 SCNetworkInterfaceRef match
;
2499 match
= createInterface(interface
, func
);
2500 if (match
!= NULL
) {
2501 CFArrayAppendValue(interfaces
, match
);
2505 IOObjectRelease(interface
);
2508 IOObjectRelease(iterator
);
2515 #pragma mark helper functions
2519 findConfiguration(CFStringRef interface_type
)
2523 for (i
= 0; i
< sizeof(configurations
)/sizeof(configurations
[0]); i
++) {
2524 if (CFEqual(interface_type
, *configurations
[i
].interface_type
)) {
2535 __SCNetworkInterfaceGetDefaultConfigurationType(SCNetworkInterfaceRef interface
)
2537 CFIndex interfaceIndex
;
2538 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2540 if (interfacePrivate
->serviceID
== NULL
) {
2541 // if not associated with a service (yet)
2542 _SCErrorSet(kSCStatusInvalidArgument
);
2546 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2547 if (interfaceIndex
== kCFNotFound
) {
2548 // unknown interface type, use per-service configuration preferences
2549 return interfacePrivate
->interface_type
; // entity
2552 if (configurations
[interfaceIndex
].entity_hardware
!= NULL
) {
2553 // if configuration information can be associated with this interface type
2554 return *configurations
[interfaceIndex
].entity_hardware
;
2557 _SCErrorSet(kSCStatusInvalidArgument
);
2564 __SCNetworkInterfaceIsValidExtendedConfigurationType(SCNetworkInterfaceRef interface
,
2565 CFStringRef extendedType
,
2566 Boolean requirePerInterface
)
2568 CFStringRef defaultType
;
2569 CFIndex extendedIndex
;
2570 CFIndex interfaceIndex
;
2571 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2572 Boolean isL2TP
= FALSE
;
2575 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
2576 if (defaultType
== NULL
) {
2580 if (CFEqual(extendedType
, defaultType
)) {
2581 // extended and default configuration types cannot conflict
2585 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2586 if (interfaceIndex
== kCFNotFound
) {
2587 // configuration information for unknown interface type's
2588 // are stored along with the service and we don't allow
2589 // per-service extended configurations
2593 if (CFEqual(extendedType
, kSCEntNetIPSec
)) {
2594 CFStringRef interfaceType
;
2596 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
2597 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
2598 SCNetworkInterfaceRef child
;
2600 child
= SCNetworkInterfaceGetInterface(interface
);
2601 if (child
!= NULL
) {
2602 interfaceType
= SCNetworkInterfaceGetInterfaceType(child
);
2603 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
2610 if (requirePerInterface
&&
2611 !configurations
[interfaceIndex
].per_interface_config
&&
2613 // we don't allow per-service extended configurations (except
2614 // that we do allow IPSec as an extended type for PPP->L2TP)
2618 extendedIndex
= findConfiguration(extendedType
);
2619 if ((extendedIndex
!= kCFNotFound
) && !isL2TP
) {
2620 // extended type cannot match a known interface type (except
2621 // that we do allow IPSec as an extended type for PPP->L2TP)
2627 * Do we match specific/known extended configuration types (e.g. EAPOL)
2628 * and ensure that any non-standard extended configuration types be of
2629 * the form com.myCompany.myType?
2638 _SCErrorSet(kSCStatusInvalidArgument
);
2645 CFStringRef defaultType
;
2646 CFMutableArrayRef types
;
2647 } extendedConfiguration
, *extendedConfigurationRef
;
2651 __addExtendedConfigurationType(const void *key
, const void *value
, void *context
)
2653 CFStringRef extendedType
= (CFStringRef
)key
;
2654 extendedConfigurationRef myContextRef
= (extendedConfigurationRef
)context
;
2656 if (CFEqual(extendedType
, myContextRef
->defaultType
)) {
2657 // do not include the default configuration type
2661 if (CFArrayContainsValue(myContextRef
->types
,
2662 CFRangeMake(0, CFArrayGetCount(myContextRef
->types
)),
2664 // if extendedType already has already been added
2668 CFArrayAppendValue(myContextRef
->types
, extendedType
);
2675 extendedConfigurationTypes(SCNetworkInterfaceRef interface
)
2678 CFIndex interfaceIndex
;
2679 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2680 extendedConfiguration myContext
;
2681 SCNetworkServiceRef service
;
2685 myContext
.defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
2686 if (myContext
.defaultType
== NULL
) {
2687 myContext
.types
= NULL
;
2691 myContext
.types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2693 if (interfacePrivate
->serviceID
== NULL
) {
2694 // if not associated with a service (yet)
2698 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2699 if (interfaceIndex
== kCFNotFound
) {
2700 // we don't allow per-service extended configurations
2704 if (!configurations
[interfaceIndex
].per_interface_config
) {
2705 // known interface type but we still don't allow
2706 // per-service extended configurations
2710 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
2711 interfacePrivate
->prefs
,
2712 interfacePrivate
->serviceID
,
2715 sets
= SCNetworkSetCopyAll(interfacePrivate
->prefs
);
2716 n
= (sets
!= NULL
) ? CFArrayGetCount(sets
) : 0;
2718 for (i
= 0; i
< n
; i
++) {
2719 CFDictionaryRef configs
;
2722 CFArrayRef services
;
2723 SCNetworkSetRef set
;
2725 set
= CFArrayGetValueAtIndex(sets
, i
);
2726 services
= SCNetworkSetCopyServices(set
);
2727 found
= CFArrayContainsValue(services
,
2728 CFRangeMake(0, CFArrayGetCount(services
)),
2730 CFRelease(services
);
2736 // add stored extended configuration types
2737 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
2738 SCNetworkSetGetSetID(set
), // set
2739 interfacePrivate
->entity_device
, // service
2741 configs
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
2743 if (isA_CFDictionary(configs
)) {
2744 CFDictionaryApplyFunction(configs
,
2745 __addExtendedConfigurationType
,
2749 // add not-yet-stored extended configuration types
2750 if (interfacePrivate
->unsaved
!= NULL
) {
2751 CFDictionaryApplyFunction(interfacePrivate
->unsaved
,
2752 __addExtendedConfigurationType
,
2760 if (sets
!= NULL
) CFRelease(sets
);
2764 return myContext
.types
;
2769 copyConfigurationPaths(SCNetworkInterfacePrivateRef interfacePrivate
,
2770 CFStringRef extendedType
)
2772 CFMutableArrayRef array
;
2774 CFIndex interfaceIndex
;
2777 SCNetworkServiceRef service
;
2780 array
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2782 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2783 if (interfaceIndex
== kCFNotFound
) {
2784 // unknown interface type, use per-service configuration preferences
2785 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
2786 interfacePrivate
->serviceID
, // service
2787 extendedType
); // entity
2788 CFArrayAppendValue(array
, path
);
2793 if (!configurations
[interfaceIndex
].per_interface_config
) {
2794 // known interface type, per-service configuration preferences
2795 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
2796 interfacePrivate
->serviceID
, // service
2797 extendedType
); // entity
2798 CFArrayAppendValue(array
, path
);
2803 // known interface type, per-interface configuration preferences
2805 // 1. look for all sets which contain the associated service
2806 // 2. add a per-set path for the interface configuration for
2809 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
2810 interfacePrivate
->prefs
,
2811 interfacePrivate
->serviceID
,
2812 (SCNetworkInterfaceRef
)interfacePrivate
);
2814 sets
= SCNetworkSetCopyAll(interfacePrivate
->prefs
);
2815 n
= (sets
!= NULL
) ? CFArrayGetCount(sets
) : 0;
2817 for (i
= 0; i
< n
; i
++) {
2818 CFArrayRef services
;
2819 SCNetworkSetRef set
;
2821 set
= CFArrayGetValueAtIndex(sets
, i
);
2822 services
= SCNetworkSetCopyServices(set
);
2823 if (CFArrayContainsValue(services
,
2824 CFRangeMake(0, CFArrayGetCount(services
)),
2826 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
2827 SCNetworkSetGetSetID(set
), // set
2828 interfacePrivate
->entity_device
, // service
2829 extendedType
); // entity
2830 CFArrayAppendValue(array
, path
);
2833 CFRelease(services
);
2836 if (CFArrayGetCount(array
) == 0) {
2842 if (sets
!= NULL
) CFRelease(sets
);
2848 #pragma mark SCNetworkInterface <--> preferences entity
2853 __SCNetworkInterfaceCopyInterfaceEntity(SCNetworkInterfaceRef interface
)
2855 CFMutableDictionaryRef entity
;
2856 CFIndex interfaceIndex
;
2857 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2859 entity
= CFDictionaryCreateMutable(NULL
,
2861 &kCFTypeDictionaryKeyCallBacks
,
2862 &kCFTypeDictionaryValueCallBacks
);
2863 if (interfacePrivate
->entity_type
!= NULL
) {
2864 CFDictionarySetValue(entity
,
2865 kSCPropNetInterfaceType
,
2866 interfacePrivate
->entity_type
);
2868 if (interfacePrivate
->entity_subtype
!= NULL
) {
2869 CFDictionarySetValue(entity
,
2870 kSCPropNetInterfaceSubType
,
2871 interfacePrivate
->entity_subtype
);
2873 if (interfacePrivate
->entity_device
!= NULL
) {
2874 CFDictionarySetValue(entity
,
2875 kSCPropNetInterfaceDeviceName
,
2876 interfacePrivate
->entity_device
);
2878 if (interfacePrivate
->entity_device_unique
!= NULL
) {
2879 CFDictionarySetValue(entity
,
2880 CFSTR("DeviceUniqueIdentifier"),
2881 interfacePrivate
->entity_device_unique
);
2883 if (interfacePrivate
->hidden
) {
2884 CFDictionarySetValue(entity
,
2885 kSCNetworkInterfaceHiddenConfigurationKey
,
2889 // match the "hardware" with the lowest layer
2891 SCNetworkInterfaceRef nextInterface
;
2893 nextInterface
= SCNetworkInterfaceGetInterface(interface
);
2894 if (nextInterface
== NULL
) {
2898 interface
= nextInterface
;
2900 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2902 if (CFEqual(interface
, kSCNetworkInterfaceIPv4
)) {
2906 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2907 if (interfaceIndex
!= kCFNotFound
) {
2908 if (configurations
[interfaceIndex
].entity_hardware
!= NULL
) {
2909 CFDictionarySetValue(entity
,
2910 kSCPropNetInterfaceHardware
,
2911 *configurations
[interfaceIndex
].entity_hardware
);
2914 CFDictionarySetValue(entity
,
2915 kSCPropNetInterfaceHardware
,
2916 interfacePrivate
->interface_type
);
2919 // add the localized display name (which will only be used when/if the
2920 // interface is removed from the system)
2921 CFDictionarySetValue(entity
,
2922 kSCPropUserDefinedName
,
2923 SCNetworkInterfaceGetLocalizedDisplayName(interface
));
2925 // note that this is a V.92 capable modem
2926 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeModem
) &&
2927 interfacePrivate
->modemIsV92
) {
2931 num
= CFNumberCreate(NULL
, kCFNumberIntType
, &one
);
2932 CFDictionarySetValue(entity
,
2933 kSCPropNetInterfaceSupportsModemOnHold
,
2942 static SCNetworkInterfaceRef
2943 findInterface(CFArrayRef interfaces
, CFStringRef match_if
)
2948 n
= CFArrayGetCount(interfaces
);
2949 for (i
= 0; i
< n
; i
++) {
2950 SCNetworkInterfaceRef interface
= CFArrayGetValueAtIndex(interfaces
, i
);
2951 CFStringRef interfaceName
;
2953 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
2954 if ((interfaceName
!= NULL
) && CFEqual(interfaceName
, match_if
)) {
2955 CFRetain(interface
);
2963 static SCNetworkInterfaceRef
2964 findBondInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
2967 SCNetworkInterfaceRef interface
= NULL
;
2969 if (prefs
== NULL
) {
2973 // check if the interface is an Ethernet Bond
2974 bonds
= SCBondInterfaceCopyAll(prefs
);
2975 if (bonds
!= NULL
) {
2976 interface
= findInterface(bonds
, ifDevice
);
2982 static SCNetworkInterfaceRef
2983 findBridgeInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
2986 SCNetworkInterfaceRef interface
= NULL
;
2988 if (prefs
== NULL
) {
2992 // check if the interface is an bridge
2993 bridges
= SCBridgeInterfaceCopyAll(prefs
);
2994 if (bridges
!= NULL
) {
2995 interface
= findInterface(bridges
, ifDevice
);
3001 static SCNetworkInterfaceRef
3002 findVLANInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
3004 SCNetworkInterfaceRef interface
= NULL
;
3007 if (prefs
== NULL
) {
3011 // check if the interface is a VLAN
3012 vlans
= SCVLANInterfaceCopyAll(prefs
);
3013 if (vlans
!= NULL
) {
3014 interface
= findInterface(vlans
, ifDevice
);
3021 SCNetworkInterfaceRef
3022 _SCNetworkInterfaceCreateWithBSDName(CFAllocatorRef allocator
,
3023 CFStringRef bsdName
,
3026 CFMutableDictionaryRef entity
;
3027 SCNetworkInterfaceRef interface
;
3029 entity
= CFDictionaryCreateMutable(NULL
,
3031 &kCFTypeDictionaryKeyCallBacks
,
3032 &kCFTypeDictionaryValueCallBacks
);
3033 CFDictionarySetValue(entity
, kSCPropNetInterfaceDeviceName
, bsdName
);
3035 if ((flags
& kIncludeBondInterfaces
) == 0) {
3036 CFDictionarySetValue(entity
, CFSTR("_NO_BOND_INTERFACES_"), kCFBooleanTrue
);
3039 if ((flags
& kIncludeBridgeInterfaces
) == 0) {
3040 CFDictionarySetValue(entity
, CFSTR("_NO_BRIDGE_INTERFACES_"), kCFBooleanTrue
);
3043 if ((flags
& kIncludeVLANInterfaces
) == 0) {
3044 CFDictionarySetValue(entity
, CFSTR("_NO_VLAN_INTERFACES_"), kCFBooleanTrue
);
3047 interface
= _SCNetworkInterfaceCreateWithEntity(NULL
, entity
, NULL
);
3055 __SCNetworkInterfaceSetService(SCNetworkInterfaceRef interface
,
3056 SCNetworkServiceRef service
)
3058 SCNetworkInterfacePrivateRef interfacePrivate
;
3059 SCNetworkServicePrivateRef servicePrivate
;
3061 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3062 if (interfacePrivate
->prefs
!= NULL
) {
3063 CFRelease(interfacePrivate
->prefs
);
3064 interfacePrivate
->prefs
= NULL
;
3066 if (interfacePrivate
->serviceID
!= NULL
) {
3067 CFRelease(interfacePrivate
->serviceID
);
3068 interfacePrivate
->serviceID
= NULL
;
3071 servicePrivate
= (SCNetworkServicePrivateRef
)service
;
3072 if (servicePrivate
->prefs
!= NULL
) {
3073 interfacePrivate
->prefs
= CFRetain(servicePrivate
->prefs
);
3075 if (servicePrivate
->serviceID
!= NULL
) {
3076 interfacePrivate
->serviceID
= CFRetain(servicePrivate
->serviceID
);
3084 _SCNetworkInterfaceMatchesName(CFStringRef name
, CFStringRef key
)
3089 if (bundle
== NULL
) {
3094 if (!isA_CFString(name
)) {
3095 // if no interface "name"
3099 // check non-localized name for a match
3100 str
= copy_interface_string(bundle
, key
, FALSE
);
3102 match
= CFEqual(name
, str
);
3109 // check localized name for a match
3110 str
= copy_interface_string(bundle
, key
, TRUE
);
3112 match
= CFEqual(name
, str
);
3123 SCNetworkInterfaceRef
3124 _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef allocator
,
3125 CFDictionaryRef interface_entity
,
3126 SCNetworkServiceRef service
)
3128 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
3129 CFStringRef ifDevice
;
3130 CFStringRef ifName
= NULL
;
3131 CFStringRef ifSubType
;
3133 CFStringRef ifUnique
;
3134 CFArrayRef matching_interfaces
= NULL
;
3136 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
3137 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
3139 ifType
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceType
);
3140 if (ifType
== NULL
) {
3142 * The interface "Type" was not specified. We'll make an
3143 * assumption that this is an "Ethernet" interface. If a
3144 * real interface exists with the provided interface name
3145 * then the actual type will be set accordingly. If not, we'll
3146 * end up crafting an "Ethernet" SCNetworkInterface which
3147 * will keep the rest of the configuration APIs happy.
3149 ifType
= kSCValNetInterfaceTypeEthernet
;
3152 if (!isA_CFString(ifType
)) {
3156 ifSubType
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceSubType
);
3157 if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) ||
3158 CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
3159 if (!isA_CFString(ifSubType
)) {
3164 ifDevice
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceDeviceName
);
3165 ifUnique
= CFDictionaryGetValue(interface_entity
, CFSTR("DeviceUniqueIdentifier"));
3167 if (CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
) ||
3168 CFEqual(ifType
, kSCValNetInterfaceTypeFireWire
) ||
3169 (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) && CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPoE
))) {
3170 char bsdName
[IFNAMSIZ
];
3171 CFMutableDictionaryRef matching
;
3173 if (!isA_CFString(ifDevice
)) {
3177 if (CFEqual(ifDevice
, CFSTR("lo0"))) { // for _SCNetworkInterfaceCreateWithBSDName
3178 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
3182 if (_SC_cfstring_to_cstring(ifDevice
, bsdName
, sizeof(bsdName
), kCFStringEncodingASCII
) == NULL
) {
3186 matching
= IOBSDNameMatching(masterPort
, 0, bsdName
);
3187 if (matching
== NULL
) {
3190 matching_interfaces
= findMatchingInterfaces(matching
, processNetworkInterface
);
3191 CFRelease(matching
);
3192 } else if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
3193 if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPSerial
)) {
3194 CFDictionaryRef matching
;
3195 CFStringRef match_keys
[2];
3196 CFStringRef match_vals
[2];
3198 if (!isA_CFString(ifDevice
)) {
3202 match_keys
[0] = CFSTR(kIOProviderClassKey
);
3203 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
3205 match_keys
[1] = CFSTR(kIOTTYBaseNameKey
);
3206 match_vals
[1] = ifDevice
;
3208 matching
= CFDictionaryCreate(NULL
,
3209 (const void **)match_keys
,
3210 (const void **)match_vals
,
3211 sizeof(match_keys
)/sizeof(match_keys
[0]),
3212 &kCFTypeDictionaryKeyCallBacks
,
3213 &kCFTypeDictionaryValueCallBacks
);
3214 matching_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
);
3215 CFRelease(matching
);
3217 if (ifUnique
== NULL
) {
3219 Boolean useDeviceName
= TRUE
;
3221 n
= (matching_interfaces
!= NULL
) ? CFArrayGetCount(matching_interfaces
) : 0;
3225 for (i
= 0; i
< n
; i
++) {
3226 SCNetworkInterfacePrivateRef scanPrivate
;
3228 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
3229 if (scanPrivate
->entity_device_unique
!= NULL
) {
3230 useDeviceName
= FALSE
;
3236 if (useDeviceName
) {
3237 if (matching_interfaces
!= NULL
) {
3238 CFRelease(matching_interfaces
);
3241 match_keys
[1] = CFSTR(kIOTTYDeviceKey
);
3242 matching
= CFDictionaryCreate(NULL
,
3243 (const void **)match_keys
,
3244 (const void **)match_vals
,
3245 sizeof(match_keys
)/sizeof(match_keys
[0]),
3246 &kCFTypeDictionaryKeyCallBacks
,
3247 &kCFTypeDictionaryValueCallBacks
);
3248 matching_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
);
3249 CFRelease(matching
);
3252 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypeL2TP
)) {
3253 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
3254 kSCNetworkInterfaceTypeL2TP
);
3255 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPTP
)) {
3256 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
3257 kSCNetworkInterfaceTypePPTP
);
3259 // XXX do we allow non-Apple variants of PPP??? XXX
3260 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
3263 } else if (CFEqual(ifType
, kSCValNetInterfaceType6to4
)) {
3264 if (!isA_CFString(ifDevice
)) {
3268 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
3269 kSCNetworkInterfaceType6to4
);
3270 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeIPSec
)) {
3271 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
3272 kSCNetworkInterfaceTypeIPSec
);
3273 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeLoopback
)) {
3274 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
3275 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
3276 if (CFStringFind(ifSubType
, CFSTR("."), 0).location
!= kCFNotFound
) {
3277 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
3280 } else if ((CFStringFind(ifType
, CFSTR("."), 0).location
!= kCFNotFound
) && (ifDevice
== NULL
)) {
3281 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
3285 if (matching_interfaces
!= NULL
) {
3287 SCPreferencesRef prefs
;
3289 n
= CFArrayGetCount(matching_interfaces
);
3292 interfacePrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, 0);
3293 if (_SC_CFEqual(ifUnique
, interfacePrivate
->entity_device_unique
)) {
3294 // if the unique ID's match
3295 CFRetain(interfacePrivate
);
3299 interfacePrivate
= NULL
;
3302 if (!CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
)) {
3305 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), NULL
);
3306 if (prefs
== NULL
) {
3309 if (!CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_BOND_INTERFACES_"))) {
3310 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findBondInterface(prefs
, ifDevice
);
3313 if ((interfacePrivate
== NULL
)
3314 && !CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_BRIDGE_INTERFACES_"))) {
3315 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findBridgeInterface(prefs
, ifDevice
);
3318 if ((interfacePrivate
== NULL
)
3319 && !CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_VLAN_INTERFACES_"))) {
3320 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findVLANInterface(prefs
, ifDevice
);
3325 if (ifUnique
!= NULL
) {
3328 // we are looking for an interface with a unique ID
3329 // so let's try to focus our choices
3330 for (i
= 0; i
< n
; i
++) {
3331 SCNetworkInterfacePrivateRef scanPrivate
;
3333 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
3334 if (_SC_CFEqual(ifUnique
, scanPrivate
->entity_device_unique
)) {
3335 if (interfacePrivate
!= NULL
) {
3336 // if we've matched more than one interface
3337 interfacePrivate
= NULL
;
3340 interfacePrivate
= scanPrivate
;
3343 } else if (CFDictionaryGetValueIfPresent(interface_entity
,
3344 kSCPropUserDefinedName
,
3345 (const void **)&ifName
)) {
3348 // we don't have a unique ID but do have an interface
3349 // name. If the matching interfaces do have IDs than
3350 // we can try to focus our choices using the name
3351 for (i
= 0; i
< n
; i
++) {
3352 SCNetworkInterfacePrivateRef scanPrivate
;
3354 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
3355 if (scanPrivate
->entity_device_unique
!= NULL
) {
3356 SCNetworkInterfaceRef scan
= (SCNetworkInterfaceRef
)scanPrivate
;
3357 CFStringRef scanName
;
3359 scanName
= __SCNetworkInterfaceGetNonLocalizedDisplayName(scan
);
3360 if ((scanName
!= NULL
) && !_SC_CFEqual(ifName
, scanName
)) {
3361 continue; // if not the same display name
3365 if (interfacePrivate
!= NULL
) {
3366 // if we've matched more than one interface
3367 interfacePrivate
= NULL
;
3370 interfacePrivate
= scanPrivate
;
3373 if (interfacePrivate
== NULL
) {
3374 SCLog(TRUE
, LOG_ERR
, CFSTR("_SCNetworkInterfaceCreateWithEntity() failed, more than one interface matches %@"), ifDevice
);
3375 interfacePrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, 0);
3377 CFRetain(interfacePrivate
);
3380 CFRelease(matching_interfaces
);
3385 if (interfacePrivate
== NULL
) {
3387 * if device not present on this system
3389 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
, NULL
);
3390 interfacePrivate
->entity_type
= ifType
;
3391 interfacePrivate
->entity_subtype
= ifSubType
;
3392 interfacePrivate
->entity_device
= (ifDevice
!= NULL
) ? CFStringCreateCopy(NULL
, ifDevice
) : NULL
;
3393 interfacePrivate
->entity_device_unique
= (ifUnique
!= NULL
) ? CFStringCreateCopy(NULL
, ifUnique
) : NULL
;
3395 if (CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
)) {
3396 CFStringRef entity_hardware
;
3398 entity_hardware
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceHardware
);
3399 if (isA_CFString((entity_hardware
)) &&
3400 CFEqual(entity_hardware
, kSCEntNetAirPort
)) {
3401 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
3402 interfacePrivate
->localized_key
= CFSTR("airport");
3403 interfacePrivate
->sort_order
= kSortAirPort
;
3407 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
3409 name
= CFDictionaryGetValue(interface_entity
, kSCPropUserDefinedName
);
3410 if (_SCNetworkInterfaceMatchesName(name
, CFSTR("iPhone"))) {
3411 interfacePrivate
->localized_key
= CFSTR("iPhone");
3412 interfacePrivate
->sort_order
= kSortTethered
;
3413 } else if (_SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-gn"))) {
3414 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-gn");
3415 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
3416 } else if (_SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-nap"))) {
3417 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-nap");
3418 interfacePrivate
->sort_order
= kSortBluetoothPAN_NAP
;
3419 } else if (_SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-u"))) {
3420 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-u");
3421 interfacePrivate
->sort_order
= kSortBluetoothPAN_U
;
3423 interfacePrivate
->sort_order
= kSortEthernet
;
3426 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeFireWire
)) {
3427 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeFireWire
;
3428 interfacePrivate
->sort_order
= kSortFireWire
;
3429 } else if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
3430 if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPoE
)) {
3431 CFStringRef entity_hardware
;
3433 entity_hardware
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceHardware
);
3434 if (isA_CFString((entity_hardware
)) &&
3435 CFEqual(entity_hardware
, kSCEntNetAirPort
)) {
3436 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
3437 interfacePrivate
->sort_order
= kSortAirPort
;
3439 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
3440 interfacePrivate
->sort_order
= kSortEthernet
;
3442 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPSerial
)) {
3443 if (CFStringHasPrefix(ifDevice
, CFSTR("Bluetooth"))) {
3444 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBluetooth
;
3445 interfacePrivate
->sort_order
= kSortBluetooth
;
3446 } else if (CFStringHasPrefix(ifDevice
, CFSTR("irda"))) {
3447 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIrDA
;
3448 interfacePrivate
->sort_order
= kSortIrDA
;
3449 } else if (CFStringHasPrefix(ifDevice
, CFSTR("wwan"))) {
3450 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeWWAN
;
3451 interfacePrivate
->sort_order
= kSortWWAN
;
3453 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeModem
;
3454 interfacePrivate
->sort_order
= kSortModem
;
3457 SCNetworkInterfaceRef child
;
3460 CFRelease(interfacePrivate
);
3461 child
= SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
, ifSubType
);
3462 interfacePrivate
= (SCNetworkInterfacePrivateRef
)child
;
3463 if (interfacePrivate
== NULL
) {
3467 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
3468 SCNetworkInterfaceRef child
;
3470 CFRelease(interfacePrivate
);
3471 child
= SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
, ifSubType
);
3472 interfacePrivate
= (SCNetworkInterfacePrivateRef
)child
;
3473 if (interfacePrivate
== NULL
) {
3476 } else if (CFStringFind(ifType
, CFSTR("."), 0).location
!= kCFNotFound
) {
3477 // if vendor interface
3478 if (vendor_interface_types
== NULL
) {
3479 vendor_interface_types
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
3481 CFSetAddValue(vendor_interface_types
, ifType
);
3483 interfacePrivate
->interface_type
= CFSetGetValue(vendor_interface_types
, ifType
);
3485 // if unknown interface
3486 CFRelease(interfacePrivate
);
3487 interfacePrivate
= NULL
;
3491 if (CFDictionaryContainsKey(interface_entity
, kSCNetworkInterfaceHiddenConfigurationKey
)) {
3492 interfacePrivate
->hidden
= TRUE
;
3496 if (service
!= NULL
) {
3497 __SCNetworkInterfaceSetService((SCNetworkInterfaceRef
)interfacePrivate
,
3500 // set prefs & serviceID to Bond member interfaces
3501 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBond
)) {
3506 members
= SCBondInterfaceGetMemberInterfaces((SCNetworkInterfaceRef
)interfacePrivate
);
3507 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
3508 for (i
= 0; i
< n
; i
++) {
3509 SCNetworkInterfaceRef member
;
3511 member
= CFArrayGetValueAtIndex(members
, i
);
3512 __SCNetworkInterfaceSetService(member
, service
);
3516 // set prefs & serviceID to Bridge member interfaces
3517 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBridge
)) {
3522 members
= SCBridgeInterfaceGetMemberInterfaces((SCNetworkInterfaceRef
)interfacePrivate
);
3523 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
3524 for (i
= 0; i
< n
; i
++) {
3525 SCNetworkInterfaceRef member
;
3527 member
= CFArrayGetValueAtIndex(members
, i
);
3528 __SCNetworkInterfaceSetService(member
, service
);
3532 // set prefs & serviceID to VLAN pyhsical interface
3533 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeVLAN
)) {
3534 SCNetworkInterfaceRef vlan_physical
;
3536 vlan_physical
= SCVLANInterfaceGetPhysicalInterface((SCNetworkInterfaceRef
)interfacePrivate
);
3537 if (vlan_physical
!= NULL
) {
3538 __SCNetworkInterfaceSetService(vlan_physical
, service
);
3543 if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
3544 SCNetworkInterfaceRef parent
;
3547 parent
= SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef
)interfacePrivate
,
3548 kSCNetworkInterfaceTypePPP
);
3549 CFRelease(interfacePrivate
);
3550 interfacePrivate
= (SCNetworkInterfacePrivateRef
)parent
;
3551 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
3552 SCNetworkInterfaceRef parent
;
3555 parent
= SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef
)interfacePrivate
,
3556 kSCNetworkInterfaceTypeVPN
);
3557 CFRelease(interfacePrivate
);
3558 interfacePrivate
= (SCNetworkInterfacePrivateRef
)parent
;
3561 return (SCNetworkInterfaceRef
)interfacePrivate
;
3566 #pragma mark SCNetworkInterface APIs
3571 __SCNetworkInterfaceCopyAll_IONetworkInterface(void)
3573 CFDictionaryRef matching
;
3574 CFArrayRef new_interfaces
;
3576 // get Ethernet, Firewire, and AirPort interfaces
3578 matching
= IOServiceMatching(kIONetworkInterfaceClass
);
3579 new_interfaces
= findMatchingInterfaces(matching
, processNetworkInterface
);
3580 CFRelease(matching
);
3582 return new_interfaces
;
3588 __SCNetworkInterfaceCopyAll_Modem()
3590 CFDictionaryRef matching
;
3591 CFStringRef match_keys
[2];
3592 CFStringRef match_vals
[2];
3593 CFArrayRef new_interfaces
;
3595 match_keys
[0] = CFSTR(kIOProviderClassKey
);
3596 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
3598 match_keys
[1] = CFSTR(kIOSerialBSDTypeKey
);
3599 match_vals
[1] = CFSTR(kIOSerialBSDModemType
);
3601 matching
= CFDictionaryCreate(NULL
,
3602 (const void **)match_keys
,
3603 (const void **)match_vals
,
3604 sizeof(match_keys
)/sizeof(match_keys
[0]),
3605 &kCFTypeDictionaryKeyCallBacks
,
3606 &kCFTypeDictionaryValueCallBacks
);
3607 new_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
);
3608 CFRelease(matching
);
3610 return new_interfaces
;
3616 __SCNetworkInterfaceCopyAll_RS232()
3618 CFDictionaryRef matching
;
3619 CFStringRef match_keys
[2];
3620 CFStringRef match_vals
[2];
3621 CFArrayRef new_interfaces
;
3623 match_keys
[0] = CFSTR(kIOProviderClassKey
);
3624 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
3626 match_keys
[1] = CFSTR(kIOSerialBSDTypeKey
);
3627 match_vals
[1] = CFSTR(kIOSerialBSDRS232Type
);
3629 matching
= CFDictionaryCreate(NULL
,
3630 (const void **)match_keys
,
3631 (const void **)match_vals
,
3632 sizeof(match_keys
)/sizeof(match_keys
[0]),
3633 &kCFTypeDictionaryKeyCallBacks
,
3634 &kCFTypeDictionaryValueCallBacks
);
3635 new_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
);
3636 CFRelease(matching
);
3638 return new_interfaces
;
3643 add_interfaces(CFMutableArrayRef all_interfaces
, CFArrayRef new_interfaces
)
3648 n
= CFArrayGetCount(new_interfaces
);
3649 for (i
= 0; i
< n
; i
++) {
3650 CFStringRef bsdName
;
3651 SCNetworkInterfaceRef interface
;
3653 interface
= CFArrayGetValueAtIndex(new_interfaces
, i
);
3654 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
3655 if (bsdName
!= NULL
) {
3656 CFArrayAppendValue(all_interfaces
, interface
);
3665 __waitForInterfaces()
3670 SCDynamicStoreRef store
;
3672 store
= SCDynamicStoreCreate(NULL
, CFSTR("SCNetworkInterfaceCopyAll"), NULL
, NULL
);
3673 if (store
== NULL
) {
3677 key
= SCDynamicStoreKeyCreate(NULL
, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin
);
3678 keys
= CFArrayCreate(NULL
, (const void **)&key
, 1, &kCFTypeArrayCallBacks
);
3679 ok
= SCDynamicStoreSetNotificationKeys(store
, keys
, NULL
);
3682 SCLog(TRUE
, LOG_ERR
,
3683 CFSTR("SCDynamicStoreSetNotificationKeys() failed: %s"), SCErrorString(SCError()));
3688 CFArrayRef changedKeys
;
3689 CFDictionaryRef dict
;
3690 Boolean quiet
= FALSE
;
3693 dict
= SCDynamicStoreCopyValue(store
, key
);
3695 if (isA_CFDictionary(dict
) &&
3696 (CFDictionaryContainsKey(dict
, CFSTR("*QUIET*")) ||
3697 CFDictionaryContainsKey(dict
, CFSTR("*TIMEOUT*")))) {
3706 ok
= SCDynamicStoreNotifyWait(store
);
3708 SCLog(TRUE
, LOG_ERR
,
3709 CFSTR("SCDynamicStoreNotifyWait() failed: %s"), SCErrorString(SCError()));
3713 changedKeys
= SCDynamicStoreCopyNotifiedKeys(store
);
3714 if (changedKeys
!= NULL
) {
3715 CFRelease(changedKeys
);
3727 CFArrayRef
/* of SCNetworkInterfaceRef's */
3728 _SCNetworkInterfaceCopyAllWithPreferences(SCPreferencesRef prefs
)
3730 CFMutableArrayRef all_interfaces
;
3731 CFArrayRef new_interfaces
;
3732 Boolean temp_preferences
= FALSE
;
3734 /* initialize runtime */
3735 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
3737 /* wait for IOKit to quiesce */
3738 pthread_once(&iokit_quiet
, __waitForInterfaces
);
3740 all_interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3742 // get Ethernet, Firewire, and AirPort interfaces
3743 new_interfaces
= __SCNetworkInterfaceCopyAll_IONetworkInterface();
3744 if (new_interfaces
!= NULL
) {
3745 add_interfaces(all_interfaces
, new_interfaces
);
3746 CFRelease(new_interfaces
);
3749 // get Modem interfaces
3750 new_interfaces
= __SCNetworkInterfaceCopyAll_Modem();
3751 if (new_interfaces
!= NULL
) {
3752 add_interfaces(all_interfaces
, new_interfaces
);
3753 CFRelease(new_interfaces
);
3756 // get serial (RS232) interfaces
3757 new_interfaces
= __SCNetworkInterfaceCopyAll_RS232();
3758 if (new_interfaces
!= NULL
) {
3759 add_interfaces(all_interfaces
, new_interfaces
);
3760 CFRelease(new_interfaces
);
3763 // get virtual network interfaces (Bond, Bridge, VLAN)
3764 if (prefs
== NULL
) {
3765 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterfaceCopyAll"), NULL
);
3766 if (prefs
!= NULL
) {
3767 temp_preferences
= TRUE
;
3770 if (prefs
!= NULL
) {
3771 new_interfaces
= SCBondInterfaceCopyAll(prefs
);
3772 if (new_interfaces
!= NULL
) {
3773 add_interfaces(all_interfaces
, new_interfaces
);
3774 CFRelease(new_interfaces
);
3777 new_interfaces
= SCBridgeInterfaceCopyAll(prefs
);
3778 if (new_interfaces
!= NULL
) {
3779 add_interfaces(all_interfaces
, new_interfaces
);
3780 CFRelease(new_interfaces
);
3783 new_interfaces
= SCVLANInterfaceCopyAll(prefs
);
3784 if (new_interfaces
!= NULL
) {
3785 add_interfaces(all_interfaces
, new_interfaces
);
3786 CFRelease(new_interfaces
);
3789 if (temp_preferences
) CFRelease(prefs
);
3792 // all interfaces have been identified, order and return
3793 sort_interfaces(all_interfaces
);
3795 return all_interfaces
;
3799 CFArrayRef
/* of SCNetworkInterfaceRef's */
3800 SCNetworkInterfaceCopyAll()
3802 CFArrayRef all_interfaces
;
3804 all_interfaces
= _SCNetworkInterfaceCopyAllWithPreferences(NULL
);
3805 return all_interfaces
;
3809 CFArrayRef
/* of kSCNetworkInterfaceTypeXXX CFStringRef's */
3810 SCNetworkInterfaceGetSupportedInterfaceTypes(SCNetworkInterfaceRef interface
)
3813 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3815 if (!isA_SCNetworkInterface(interface
)) {
3816 _SCErrorSet(kSCStatusInvalidArgument
);
3820 if (interfacePrivate
->supported_interface_types
!= NULL
) {
3824 i
= findConfiguration(interfacePrivate
->interface_type
);
3825 if (i
!= kCFNotFound
) {
3826 if (configurations
[i
].supported_interfaces
!= doNone
) {
3827 interfacePrivate
->supported_interface_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3828 if (configurations
[i
].supported_interfaces
& do6to4
) {
3829 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceType6to4
);
3831 if (configurations
[i
].supported_interfaces
& doL2TP
) {
3832 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeL2TP
);
3834 if (configurations
[i
].supported_interfaces
& doPPP
) {
3835 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypePPP
);
3837 if (configurations
[i
].supported_interfaces
& doPPTP
) {
3838 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypePPTP
);
3840 if (configurations
[i
].supported_interfaces
& doIPSec
) {
3841 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeIPSec
);
3845 SCNetworkInterfaceRef child
;
3847 child
= SCNetworkInterfaceGetInterface(interface
);
3848 if ((child
!= NULL
) && CFEqual(child
, kSCNetworkInterfaceIPv4
)) {
3849 interfacePrivate
->supported_interface_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3850 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeVPN
);
3856 return interfacePrivate
->supported_interface_types
;
3860 CFArrayRef
/* of kSCNetworkProtocolTypeXXX CFStringRef's */
3861 SCNetworkInterfaceGetSupportedProtocolTypes(SCNetworkInterfaceRef interface
)
3864 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3866 if (!isA_SCNetworkInterface(interface
)) {
3867 _SCErrorSet(kSCStatusInvalidArgument
);
3871 if (interfacePrivate
->supported_protocol_types
!= NULL
) {
3875 i
= findConfiguration(interfacePrivate
->interface_type
);
3876 if (i
!= kCFNotFound
) {
3877 if (configurations
[i
].supported_protocols
!= doNone
) {
3878 interfacePrivate
->supported_protocol_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3879 if (configurations
[i
].supported_protocols
& doDNS
) {
3880 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeDNS
);
3882 if (configurations
[i
].supported_protocols
& doIPv4
) {
3883 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeIPv4
);
3885 if (configurations
[i
].supported_protocols
& doIPv6
) {
3886 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeIPv6
);
3888 if (configurations
[i
].supported_protocols
& doProxies
) {
3889 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeProxies
);
3891 #if !TARGET_OS_IPHONE
3892 if (configurations
[i
].supported_protocols
& doSMB
) {
3893 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeSMB
);
3895 #endif // !TARGET_OS_IPHONE
3901 return interfacePrivate
->supported_protocol_types
;
3905 SCNetworkInterfaceRef
3906 SCNetworkInterfaceCreateWithInterface(SCNetworkInterfaceRef child
, CFStringRef interfaceType
)
3908 SCNetworkInterfacePrivateRef childPrivate
= (SCNetworkInterfacePrivateRef
)child
;
3910 SCNetworkInterfacePrivateRef parentPrivate
;
3912 if (!isA_SCNetworkInterface(child
)) {
3913 _SCErrorSet(kSCStatusInvalidArgument
);
3917 if (!isA_CFString(interfaceType
)) {
3918 _SCErrorSet(kSCStatusInvalidArgument
);
3922 if (CFEqual(child
, kSCNetworkInterfaceLoopback
)) {
3923 // can't layer on top of loopback
3924 _SCErrorSet(kSCStatusInvalidArgument
);
3928 childIndex
= findConfiguration(childPrivate
->interface_type
);
3930 parentPrivate
= __SCNetworkInterfaceCreatePrivate(NULL
,
3932 childPrivate
->prefs
,
3933 childPrivate
->serviceID
,
3935 if (parentPrivate
== NULL
) {
3936 _SCErrorSet(kSCStatusFailed
);
3940 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
3941 parentPrivate
->interface_type
= kSCNetworkInterfaceTypePPP
;
3942 parentPrivate
->entity_type
= kSCValNetInterfaceTypePPP
;
3945 if (childIndex
!= kCFNotFound
) {
3946 if (configurations
[childIndex
].ppp_subtype
!= NULL
) {
3947 parentPrivate
->entity_subtype
= *configurations
[childIndex
].ppp_subtype
;
3949 // sorry, the child interface does not support PPP
3953 // if the child's interface type not known, use the child entities "Type"
3954 parentPrivate
->entity_subtype
= childPrivate
->entity_type
;
3957 if (childPrivate
->entity_device
!= NULL
) {
3958 parentPrivate
->entity_device
= CFStringCreateCopy(NULL
, childPrivate
->entity_device
);
3961 if (childPrivate
->entity_device_unique
!= NULL
) {
3962 parentPrivate
->entity_device_unique
= CFStringCreateCopy(NULL
, childPrivate
->entity_device_unique
);
3964 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
3965 if ((childIndex
== kCFNotFound
) ||
3966 ((configurations
[childIndex
].supported_interfaces
& doL2TP
) != doL2TP
)) {
3967 // if the child interface does not support L2TP
3970 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeL2TP
;
3971 parentPrivate
->localized_key
= CFSTR("l2tp");
3972 parentPrivate
->entity_type
= kSCEntNetL2TP
; // interface config goes into "L2TP"
3973 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPTP
)) {
3974 if ((childIndex
== kCFNotFound
) ||
3975 ((configurations
[childIndex
].supported_interfaces
& doPPTP
) != doPPTP
)) {
3976 // if the child interface does not support PPTP
3979 parentPrivate
->interface_type
= kSCNetworkInterfaceTypePPTP
;
3980 parentPrivate
->localized_key
= CFSTR("pptp");
3981 parentPrivate
->entity_type
= kSCEntNetPPTP
; // interface config goes into "PPTP"
3982 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceType6to4
)) {
3983 if ((childIndex
== kCFNotFound
) ||
3984 ((configurations
[childIndex
].supported_interfaces
& do6to4
) != do6to4
)) {
3985 // if the child interface does not support 6to4
3989 parentPrivate
->interface_type
= kSCNetworkInterfaceType6to4
;
3990 parentPrivate
->localized_key
= CFSTR("6to4");
3991 parentPrivate
->entity_type
= kSCValNetInterfaceType6to4
;
3992 parentPrivate
->entity_device
= CFRetain(CFSTR("stf0"));
3993 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
3994 if ((childIndex
== kCFNotFound
) ||
3995 ((configurations
[childIndex
].supported_interfaces
& doIPSec
) != doIPSec
)) {
3996 // if the child interface does not support IPSec
3999 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeIPSec
;
4000 parentPrivate
->localized_key
= CFSTR("ipsec");
4001 parentPrivate
->entity_type
= kSCValNetInterfaceTypeIPSec
;
4002 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) {
4003 if (childIndex
!= kCFNotFound
) {
4004 // if not a "vendor" child interface
4008 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeVPN
;
4009 parentPrivate
->localized_key
= CFSTR("vpn");
4010 parentPrivate
->localized_arg1
= CFRetain(childPrivate
->entity_type
);
4011 parentPrivate
->entity_type
= kSCValNetInterfaceTypeVPN
;
4012 parentPrivate
->entity_subtype
= childPrivate
->entity_type
;
4013 if (childPrivate
->entity_device
!= NULL
) {
4014 parentPrivate
->entity_device
= CFStringCreateCopy(NULL
, childPrivate
->entity_device
);
4016 if (parentPrivate
->entity_subtype
!= NULL
) {
4017 CFArrayRef components
;
4019 CFStringRef vpnType
;
4022 // the "default" interface name is derived from the VPN type
4025 // com.apple.Apple-VPN.vpnplugin --> "Apple VPN"
4028 vpnType
= parentPrivate
->entity_subtype
;
4029 components
= CFStringCreateArrayBySeparatingStrings(NULL
, vpnType
, CFSTR("."));
4030 n
= CFArrayGetCount(components
);
4032 CFEqual(CFArrayGetValueAtIndex(components
, n
- 1), CFSTR("vpnplugin"))) {
4033 CFMutableStringRef str
;
4035 str
= CFStringCreateMutableCopy(NULL
,
4037 CFArrayGetValueAtIndex(components
, n
- 2));
4038 (void) CFStringFindAndReplace(str
,
4041 CFRangeMake(0, CFStringGetLength(str
)),
4043 parentPrivate
->localized_name
= str
;
4045 CFRelease(components
);
4047 } else if (CFStringFind(interfaceType
, CFSTR("."), 0).location
!= kCFNotFound
) {
4048 // if custom interface type
4049 if (vendor_interface_types
== NULL
) {
4050 vendor_interface_types
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
4052 CFSetAddValue(vendor_interface_types
, interfaceType
);
4054 parentPrivate
->interface_type
= CFSetGetValue(vendor_interface_types
, interfaceType
);
4055 parentPrivate
->entity_type
= parentPrivate
->interface_type
; // interface config goes into a
4056 // a dictionary with the same
4057 // name as the interfaceType
4059 // unknown interface type
4063 parentPrivate
->hidden
= childPrivate
->hidden
;
4065 if (childPrivate
->overrides
!= NULL
) {
4066 parentPrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, childPrivate
->overrides
);
4069 // The following change handles the case where a user has both an Ethernet and
4070 // PPPoE network service. Because a PPPoE service is typically associated with
4071 // an ISP we want it to be sorted higher in the service order.
4072 if ((parentPrivate
->entity_subtype
!= NULL
) &&
4073 (CFEqual(parentPrivate
->entity_subtype
, kSCValNetInterfaceSubTypePPPoE
))) {
4074 if ((childPrivate
->interface_type
!= NULL
) &&
4075 (CFEqual(childPrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
))) {
4076 parentPrivate
->sort_order
= kSortAirportPPP
;
4078 parentPrivate
->sort_order
= kSortEthernetPPP
;
4081 // set sort order of the parent to match the child interface
4082 parentPrivate
->sort_order
= childPrivate
->sort_order
;
4085 return (SCNetworkInterfaceRef
)parentPrivate
;
4089 CFRelease(parentPrivate
);
4090 _SCErrorSet(kSCStatusInvalidArgument
);
4097 __SCNetworkInterfaceGetDefaultConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
)
4099 CFDictionaryRef config
= NULL
;
4100 CFStringRef defaultType
;
4101 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4103 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
4104 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4106 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
4107 if (defaultType
!= NULL
) {
4111 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
4112 SCNetworkSetGetSetID(set
), // set
4113 interfacePrivate
->entity_device
, // interface
4114 defaultType
); // entity
4116 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
4119 if (config
== NULL
) {
4120 // if the "set" does not have a saved configuration, use
4121 // the [template] "interface" configuration
4122 if (interfacePrivate
->unsaved
!= NULL
) {
4123 config
= CFDictionaryGetValue(interfacePrivate
->unsaved
, defaultType
);
4124 if (config
== (CFDictionaryRef
)kCFNull
) {
4129 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
4140 static CFDictionaryRef
4141 __SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface
,
4142 CFStringRef extendedType
)
4144 CFDictionaryRef config
= NULL
;
4145 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4148 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
4149 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4151 paths
= copyConfigurationPaths(interfacePrivate
, extendedType
);
4152 if (paths
!= NULL
) {
4155 path
= CFArrayGetValueAtIndex(paths
, 0);
4156 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
4160 if (interfacePrivate
->unsaved
!= NULL
) {
4161 config
= CFDictionaryGetValue(interfacePrivate
->unsaved
, extendedType
);
4162 if (config
== (CFDictionaryRef
)kCFNull
) {
4168 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
4177 SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface
)
4179 CFDictionaryRef config
;
4180 CFStringRef defaultType
;
4182 if (!isA_SCNetworkInterface(interface
)) {
4183 _SCErrorSet(kSCStatusInvalidArgument
);
4187 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
4188 if (defaultType
== NULL
) {
4192 config
= __SCNetworkInterfaceGetConfiguration(interface
, defaultType
);
4193 if (config
== NULL
) {
4194 if (CFEqual(defaultType
, kSCEntNetAirPort
)) {
4195 SCNetworkInterfacePrivateRef interfacePrivate
;
4198 // if AirPort interface, check for a per-service config
4199 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4200 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
4201 interfacePrivate
->serviceID
, // service
4202 kSCEntNetAirPort
); // entity
4203 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
4207 if (config
== NULL
) {
4208 _SCErrorSet(kSCStatusOK
);
4216 SCNetworkInterfaceGetExtendedConfiguration(SCNetworkInterfaceRef interface
,
4217 CFStringRef extendedType
)
4219 CFDictionaryRef config
;
4221 if (!isA_SCNetworkInterface(interface
)) {
4222 _SCErrorSet(kSCStatusInvalidArgument
);
4226 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, TRUE
)) {
4227 _SCErrorSet(kSCStatusInvalidArgument
);
4231 config
= __SCNetworkInterfaceGetConfiguration(interface
, extendedType
);
4232 if (config
== NULL
) {
4233 _SCErrorSet(kSCStatusOK
);
4241 SCNetworkInterfaceGetBSDName(SCNetworkInterfaceRef interface
)
4243 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4245 if (!isA_SCNetworkInterface(interface
)) {
4246 _SCErrorSet(kSCStatusInvalidArgument
);
4250 if ((interfacePrivate
->interface
!= NULL
) &&
4251 (interfacePrivate
->interface
!= kSCNetworkInterfaceIPv4
)) {
4252 _SCErrorSet(kSCStatusOK
);
4256 return interfacePrivate
->entity_device
;
4261 SCNetworkInterfaceGetHardwareAddressString(SCNetworkInterfaceRef interface
)
4263 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4265 if (!isA_SCNetworkInterface(interface
)) {
4266 _SCErrorSet(kSCStatusInvalidArgument
);
4270 if ((interfacePrivate
->address
!= NULL
) &&
4271 (interfacePrivate
->addressString
== NULL
)) {
4275 char mac
[sizeof("xx:xx:xx:xx:xx:xx:xx:xx")];
4278 bp
= (uint8_t *)CFDataGetBytePtr(interfacePrivate
->address
);
4279 n
= CFDataGetLength(interfacePrivate
->address
) * 3;
4281 if (n
> sizeof(mac
)) {
4282 mac_p
= CFAllocatorAllocate(NULL
, 0, n
);
4285 for (cp
= mac_p
; n
> 0; n
-= 3) {
4286 cp
+= snprintf(cp
, n
, "%2.2x:", *bp
++);
4289 interfacePrivate
->addressString
= CFStringCreateWithCString(NULL
, mac_p
, kCFStringEncodingUTF8
);
4290 if (mac_p
!= mac
) CFAllocatorDeallocate(NULL
, mac_p
);
4293 return interfacePrivate
->addressString
;
4297 SCNetworkInterfaceRef
4298 SCNetworkInterfaceGetInterface(SCNetworkInterfaceRef interface
)
4300 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4302 if (!isA_SCNetworkInterface(interface
)) {
4303 _SCErrorSet(kSCStatusInvalidArgument
);
4307 return interfacePrivate
->interface
;
4312 SCNetworkInterfaceGetInterfaceType(SCNetworkInterfaceRef interface
)
4314 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4316 if (!isA_SCNetworkInterface(interface
)) {
4317 _SCErrorSet(kSCStatusInvalidArgument
);
4321 return interfacePrivate
->interface_type
;
4326 copy_interface_string(CFBundleRef bundle
, CFStringRef key
, Boolean localized
)
4328 CFStringRef str
= NULL
;
4331 str
= CFBundleCopyLocalizedString(bundle
,
4334 NETWORKINTERFACE_LOCALIZATIONS
);
4336 str
= _SC_CFBundleCopyNonLocalizedString(bundle
,
4339 NETWORKINTERFACE_LOCALIZATIONS
);
4347 copy_display_name(SCNetworkInterfaceRef interface
, Boolean localized
, Boolean oldLocalization
)
4349 CFMutableStringRef local
;
4352 local
= CFStringCreateMutable(NULL
, 0);
4354 while (interface
!= NULL
) {
4355 Boolean added
= FALSE
;
4356 SCNetworkInterfaceRef child
= NULL
;
4357 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4359 if ((interfacePrivate
->interface
!= NULL
) &&
4360 (interfacePrivate
->interface
!= kSCNetworkInterfaceIPv4
) &&
4361 !CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeVPN
)) {
4362 child
= interfacePrivate
->interface
;
4365 if ((bundle
!= NULL
) && (interfacePrivate
->localized_key
!= NULL
)) {
4367 CFStringRef key
= interfacePrivate
->localized_key
;
4369 if (oldLocalization
) {
4370 key
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("X-%@"),
4371 interfacePrivate
->localized_key
);
4373 fmt
= copy_interface_string(bundle
, key
, localized
);
4375 CFStringAppendFormat(local
,
4378 interfacePrivate
->localized_arg1
,
4379 interfacePrivate
->localized_arg2
);
4383 if (oldLocalization
) {
4389 (interfacePrivate
->prefs
!= NULL
) &&
4390 (interfacePrivate
->serviceID
!= NULL
) &&
4392 CFDictionaryRef entity
;
4395 // check for (and use) the name of the interface when it
4396 // was last available
4397 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,
4398 interfacePrivate
->serviceID
,
4399 kSCEntNetInterface
);
4400 entity
= SCPreferencesPathGetValue(interfacePrivate
->prefs
, path
);
4402 if (isA_CFDictionary(entity
)) {
4405 name
= CFDictionaryGetValue(entity
, kSCPropUserDefinedName
);
4406 if (isA_CFString(name
)) {
4407 CFStringAppend(local
, name
);
4414 // create (non-)localized name based on the interface type
4415 CFStringAppend(local
, interfacePrivate
->interface_type
);
4417 // ... and, if this is a leaf node, the interface device
4418 if ((interfacePrivate
->entity_device
!= NULL
) && (child
== NULL
)) {
4419 CFStringAppendFormat(local
, NULL
, CFSTR(" (%@)"), interfacePrivate
->entity_device
);
4423 if (child
!= NULL
) {
4424 // if this interface is layered over another
4425 CFStringAppend(local
, CFSTR(" --> "));
4431 name
= CFStringCreateCopy(NULL
, local
);
4438 #if !TARGET_OS_EMBEDDED && !TARGET_IPHONE_SIMULATOR
4441 __SCNetworkInterfaceCopyXLocalizedDisplayName(SCNetworkInterfaceRef interface
)
4445 if (!isA_SCNetworkInterface(interface
)) {
4446 _SCErrorSet(kSCStatusInvalidArgument
);
4450 name
= copy_display_name(interface
, TRUE
, TRUE
);
4457 __SCNetworkInterfaceCopyXNonLocalizedDisplayName(SCNetworkInterfaceRef interface
)
4459 CFStringRef localized_name
;
4461 if (!isA_SCNetworkInterface(interface
)) {
4462 _SCErrorSet(kSCStatusInvalidArgument
);
4466 localized_name
= copy_display_name(interface
, FALSE
, TRUE
);
4467 return localized_name
;
4469 #endif // !TARGET_OS_EMBEDDED && !TARGET_IPHONE_SIMULATOR
4474 __SCNetworkInterfaceGetNonLocalizedDisplayName(SCNetworkInterfaceRef interface
)
4476 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4478 if (!isA_SCNetworkInterface(interface
)) {
4479 _SCErrorSet(kSCStatusInvalidArgument
);
4483 if (interfacePrivate
->name
== NULL
) {
4484 interfacePrivate
->name
= copy_display_name(interface
, FALSE
, FALSE
);
4487 return interfacePrivate
->name
;
4492 SCNetworkInterfaceGetLocalizedDisplayName(SCNetworkInterfaceRef interface
)
4494 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4496 if (!isA_SCNetworkInterface(interface
)) {
4497 _SCErrorSet(kSCStatusInvalidArgument
);
4501 if (interfacePrivate
->localized_name
== NULL
) {
4502 interfacePrivate
->localized_name
= copy_display_name(interface
, TRUE
, FALSE
);
4505 return interfacePrivate
->localized_name
;
4511 __SCNetworkInterfaceGetTemplateOverrides(SCNetworkInterfaceRef interface
, CFStringRef overrideType
)
4513 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4514 CFDictionaryRef overrides
= NULL
;
4516 if (interfacePrivate
->overrides
!= NULL
) {
4517 overrides
= CFDictionaryGetValue(interfacePrivate
->overrides
, overrideType
);
4525 SCNetworkInterfaceGetTypeID(void)
4527 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
); /* initialize runtime */
4528 return __kSCNetworkInterfaceTypeID
;
4534 __SCNetworkInterfaceSetDefaultConfiguration(SCNetworkSetRef set
,
4535 SCNetworkInterfaceRef interface
,
4536 CFStringRef defaultType
,
4537 CFDictionaryRef config
,
4540 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4543 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
4544 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4546 if (defaultType
== NULL
) {
4547 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
4548 if (defaultType
== NULL
) {
4553 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
4560 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
4561 SCNetworkSetGetSetID(set
), // set
4562 interfacePrivate
->entity_device
, // interface
4563 defaultType
); // entity
4565 ok
= __setPrefsConfiguration(interfacePrivate
->prefs
, path
, config
, FALSE
);
4568 // if configuration has been saved
4569 if (interfacePrivate
->unsaved
!= NULL
) {
4570 CFDictionaryRemoveValue(interfacePrivate
->unsaved
, defaultType
);
4571 if (CFDictionaryGetCount(interfacePrivate
->unsaved
) == 0) {
4572 CFRelease(interfacePrivate
->unsaved
);
4573 interfacePrivate
->unsaved
= NULL
;
4579 if (config
== NULL
) {
4580 // remember that we are clearing the configuration
4581 config
= (CFDictionaryRef
)kCFNull
;
4584 if (interfacePrivate
->unsaved
== NULL
) {
4585 interfacePrivate
->unsaved
= CFDictionaryCreateMutable(NULL
,
4587 &kCFTypeDictionaryKeyCallBacks
,
4588 &kCFTypeDictionaryValueCallBacks
);
4590 CFDictionarySetValue(interfacePrivate
->unsaved
, defaultType
, config
);
4593 _SCErrorSet(kSCStatusNoKey
);
4604 __SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface
,
4605 CFStringRef extendedType
,
4606 CFDictionaryRef config
,
4609 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4613 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
4614 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4616 if (extendedType
== NULL
) {
4617 extendedType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
4618 if (extendedType
== NULL
) {
4623 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
4627 paths
= copyConfigurationPaths(interfacePrivate
, extendedType
);
4628 if (paths
!= NULL
) {
4632 n
= CFArrayGetCount(paths
);
4633 for (i
= 0; i
< n
; i
++) {
4636 path
= CFArrayGetValueAtIndex(paths
, i
);
4637 ok
= __setPrefsConfiguration(interfacePrivate
->prefs
, path
, config
, FALSE
);
4644 // if configuration has been saved
4645 if (interfacePrivate
->unsaved
!= NULL
) {
4646 CFDictionaryRemoveValue(interfacePrivate
->unsaved
, extendedType
);
4647 if (CFDictionaryGetCount(interfacePrivate
->unsaved
) == 0) {
4648 CFRelease(interfacePrivate
->unsaved
);
4649 interfacePrivate
->unsaved
= NULL
;
4657 if (config
== NULL
) {
4658 // remember that we are clearing the configuration
4659 config
= (CFDictionaryRef
)kCFNull
;
4662 if (interfacePrivate
->unsaved
== NULL
) {
4663 interfacePrivate
->unsaved
= CFDictionaryCreateMutable(NULL
,
4665 &kCFTypeDictionaryKeyCallBacks
,
4666 &kCFTypeDictionaryValueCallBacks
);
4668 CFDictionarySetValue(interfacePrivate
->unsaved
, extendedType
, config
);
4671 _SCErrorSet(kSCStatusNoKey
);
4680 SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface
, CFDictionaryRef config
)
4682 CFStringRef defaultType
;
4684 if (!isA_SCNetworkInterface(interface
)) {
4685 _SCErrorSet(kSCStatusInvalidArgument
);
4689 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
4690 if (defaultType
== NULL
) {
4694 return __SCNetworkInterfaceSetConfiguration(interface
, defaultType
, config
, FALSE
);
4699 SCNetworkInterfaceSetExtendedConfiguration(SCNetworkInterfaceRef interface
,
4700 CFStringRef extendedType
,
4701 CFDictionaryRef config
)
4703 if (!isA_SCNetworkInterface(interface
)) {
4704 _SCErrorSet(kSCStatusInvalidArgument
);
4708 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, TRUE
)) {
4712 return __SCNetworkInterfaceSetConfiguration(interface
, extendedType
, config
, FALSE
);
4717 #pragma mark SCNetworkInterface [Refresh Configuration] API
4720 #ifndef kSCEntNetRefreshConfiguration
4721 #define kSCEntNetRefreshConfiguration CFSTR("RefreshConfiguration")
4722 #endif // kSCEntNetRefreshConfiguration
4725 _SCNetworkInterfaceForceConfigurationRefresh(CFStringRef ifName
)
4729 SCDynamicStoreRef store
;
4731 if (!isA_CFString(ifName
)) {
4732 _SCErrorSet(kSCStatusInvalidArgument
);
4736 store
= SCDynamicStoreCreate(NULL
, CFSTR("_SCNetworkInterfaceForceConfigurationRefresh"), NULL
, NULL
);
4737 if (store
== NULL
) {
4741 key
= SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL
,
4742 kSCDynamicStoreDomainState
,
4744 kSCEntNetRefreshConfiguration
);
4745 ok
= SCDynamicStoreNotifyValue(store
, key
);
4753 __SCNetworkInterfaceForceConfigurationRefresh_helper(SCPreferencesRef prefs
, CFStringRef ifName
)
4755 CFDataRef data
= NULL
;
4757 SCPreferencesPrivateRef prefsPrivate
= (SCPreferencesPrivateRef
)prefs
;
4758 uint32_t status
= kSCStatusOK
;
4759 CFDataRef reply
= NULL
;
4761 if (prefsPrivate
->helper_port
== MACH_PORT_NULL
) {
4762 ok
= __SCPreferencesCreate_helper(prefs
);
4768 // serialize the interface name
4769 ok
= _SCSerializeString(ifName
, &data
, NULL
, NULL
);
4774 // have the helper "refresh" the configuration
4775 status
= kSCStatusOK
;
4777 ok
= _SCHelperExec(prefsPrivate
->helper_port
,
4778 SCHELPER_MSG_INTERFACE_REFRESH
,
4782 if (data
!= NULL
) CFRelease(data
);
4787 if (status
!= kSCStatusOK
) {
4796 if (prefsPrivate
->helper_port
!= MACH_PORT_NULL
) {
4797 _SCHelperClose(&prefsPrivate
->helper_port
);
4800 status
= kSCStatusAccessError
;
4805 _SCErrorSet(status
);
4811 SCNetworkInterfaceForceConfigurationRefresh(SCNetworkInterfaceRef interface
)
4814 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4816 if (!isA_SCNetworkInterface(interface
)) {
4817 _SCErrorSet(kSCStatusInvalidArgument
);
4821 ifName
= SCNetworkInterfaceGetBSDName(interface
);
4822 if (ifName
== NULL
) {
4823 _SCErrorSet(kSCStatusInvalidArgument
);
4827 if (interfacePrivate
->prefs
!= NULL
) {
4828 SCPreferencesRef prefs
= interfacePrivate
->prefs
;
4829 SCPreferencesPrivateRef prefsPrivate
= (SCPreferencesPrivateRef
)prefs
;
4831 if (prefsPrivate
->authorizationData
!= NULL
) {
4832 return __SCNetworkInterfaceForceConfigurationRefresh_helper(prefs
, ifName
);
4836 return _SCNetworkInterfaceForceConfigurationRefresh(ifName
);
4841 SCNetworkInterfaceRefreshConfiguration(CFStringRef ifName
)
4843 return _SCNetworkInterfaceForceConfigurationRefresh(ifName
);
4848 #pragma mark SCNetworkInterface Password APIs
4852 getPasswordID(CFDictionaryRef config
, CFStringRef serviceID
)
4854 CFStringRef unique_id
= NULL
;
4856 if (config
!= NULL
) {
4857 CFStringRef encryption
;
4859 encryption
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPasswordEncryption
);
4860 if (isA_CFString(encryption
) &&
4861 CFEqual(encryption
, kSCValNetPPPAuthPasswordEncryptionKeychain
)) {
4862 unique_id
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPassword
);
4865 if (unique_id
== NULL
) {
4866 unique_id
= serviceID
;
4874 copySharedSecretID(CFDictionaryRef config
, CFStringRef serviceID
)
4876 CFMutableStringRef shared_id
= NULL
;
4878 if (config
!= NULL
) {
4879 CFStringRef encryption
;
4881 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecretEncryption
);
4882 if (isA_CFString(encryption
) &&
4883 CFEqual(encryption
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) {
4884 shared_id
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecret
);
4885 if (shared_id
!= NULL
) {
4886 CFRetain(shared_id
);
4891 if (shared_id
== NULL
) {
4892 CFStringRef unique_id
;
4894 unique_id
= getPasswordID(config
, serviceID
);
4895 shared_id
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
4896 CFStringAppend(shared_id
, CFSTR(".SS"));
4904 copyXAuthID(CFDictionaryRef config
, CFStringRef serviceID
)
4906 CFMutableStringRef xauth_id
= NULL
;
4908 if (config
!= NULL
) {
4909 CFStringRef encryption
;
4911 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPasswordEncryption
);
4912 if (isA_CFString(encryption
) &&
4913 CFEqual(encryption
, kSCValNetIPSecXAuthPasswordEncryptionKeychain
)) {
4914 xauth_id
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPassword
);
4915 if (xauth_id
!= NULL
) {
4921 if (xauth_id
== NULL
) {
4922 CFStringRef unique_id
;
4924 unique_id
= getPasswordID(config
, serviceID
);
4925 xauth_id
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
4926 CFStringAppend(xauth_id
, CFSTR(".XAUTH"));
4934 checkInterfacePassword(SCNetworkInterfaceRef interface
,
4935 SCNetworkInterfacePasswordType passwordType
,
4936 SCPreferencesRef
*prefs
,
4937 CFStringRef
*serviceID
)
4939 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4941 if (!isA_SCNetworkInterface(interface
)) {
4945 *serviceID
= interfacePrivate
->serviceID
;
4946 if (*serviceID
== NULL
) {
4950 *prefs
= interfacePrivate
->prefs
;
4951 if (*prefs
== NULL
) {
4955 switch (passwordType
) {
4956 case kSCNetworkInterfacePasswordTypePPP
: {
4957 CFStringRef interfaceType
;
4959 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
4960 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
4968 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
4969 CFStringRef interfaceType
;
4971 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
4972 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
4973 interface
= SCNetworkInterfaceGetInterface(interface
);
4974 if (interface
!= NULL
) {
4975 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
4976 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
4977 // if PPP->L2TP interface
4981 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
4982 // if IPSec interface
4989 case kSCNetworkInterfacePasswordTypeEAPOL
: {
4993 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
4994 CFStringRef interfaceType
;
4996 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
4997 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
4998 // if IPSec interface
5005 case kSCNetworkInterfacePasswordTypeVPN
: {
5006 CFStringRef interfaceType
;
5008 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
5009 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) {
5025 _SCErrorSet(kSCStatusInvalidArgument
);
5031 SCNetworkInterfaceCheckPassword(SCNetworkInterfaceRef interface
,
5032 SCNetworkInterfacePasswordType passwordType
)
5034 Boolean exists
= FALSE
;
5035 SCPreferencesRef prefs
= NULL
;
5036 CFStringRef serviceID
= NULL
;
5038 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
5042 switch (passwordType
) {
5043 case kSCNetworkInterfacePasswordTypePPP
: {
5044 CFDictionaryRef config
;
5045 CFStringRef unique_id
;
5047 // get configuration
5048 config
= SCNetworkInterfaceGetConfiguration(interface
);
5051 unique_id
= getPasswordID(config
, serviceID
);
5054 exists
= __extract_password(prefs
,
5056 kSCPropNetPPPAuthPassword
,
5057 kSCPropNetPPPAuthPasswordEncryption
,
5058 kSCValNetPPPAuthPasswordEncryptionKeychain
,
5064 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
5065 CFDictionaryRef config
;
5067 CFStringRef shared_id
;
5069 // get configuration
5070 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
5072 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
5074 config
= SCNetworkInterfaceGetConfiguration(interface
);
5077 // get sharedSecret ID
5078 shared_id
= copySharedSecretID(config
, serviceID
);
5081 exists
= __extract_password(prefs
,
5083 kSCPropNetIPSecSharedSecret
,
5084 kSCPropNetIPSecSharedSecretEncryption
,
5085 kSCValNetIPSecSharedSecretEncryptionKeychain
,
5088 CFRelease(shared_id
);
5092 case kSCNetworkInterfacePasswordTypeEAPOL
: {
5093 CFDictionaryRef config
;
5094 CFStringRef unique_id
= NULL
;
5096 // get configuration
5097 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
5099 // get 802.1X identifier
5100 if (config
!= NULL
) {
5101 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
5103 if (!isA_CFString(unique_id
)) {
5108 exists
= _SCPreferencesSystemKeychainPasswordItemExists(prefs
, unique_id
);
5112 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
5113 CFDictionaryRef config
;
5114 CFStringRef xauth_id
;
5116 // get configuration
5117 config
= SCNetworkInterfaceGetConfiguration(interface
);
5120 xauth_id
= copyXAuthID(config
, serviceID
);
5123 exists
= __extract_password(prefs
,
5125 kSCPropNetIPSecXAuthPassword
,
5126 kSCPropNetIPSecXAuthPasswordEncryption
,
5127 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
5130 CFRelease(xauth_id
);
5134 case kSCNetworkInterfacePasswordTypeVPN
: {
5135 CFDictionaryRef config
;
5138 // get configuration
5139 config
= SCNetworkInterfaceGetConfiguration(interface
);
5142 vpn_id
= getPasswordID(config
, serviceID
);
5145 exists
= __extract_password(prefs
,
5147 kSCPropNetVPNAuthPassword
,
5148 kSCPropNetVPNAuthPasswordEncryption
,
5149 kSCValNetVPNAuthPasswordEncryptionKeychain
,
5156 _SCErrorSet(kSCStatusInvalidArgument
);
5165 SCNetworkInterfaceCopyPassword(SCNetworkInterfaceRef interface
,
5166 SCNetworkInterfacePasswordType passwordType
)
5168 CFDataRef password
= NULL
;
5169 SCPreferencesRef prefs
= NULL
;
5170 CFStringRef serviceID
= NULL
;
5172 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
5176 switch (passwordType
) {
5177 case kSCNetworkInterfacePasswordTypePPP
: {
5178 CFDictionaryRef config
;
5179 CFStringRef unique_id
;
5181 // get configuration
5182 config
= SCNetworkInterfaceGetConfiguration(interface
);
5185 unique_id
= getPasswordID(config
, serviceID
);
5188 (void) __extract_password(prefs
,
5190 kSCPropNetPPPAuthPassword
,
5191 kSCPropNetPPPAuthPasswordEncryption
,
5192 kSCValNetPPPAuthPasswordEncryptionKeychain
,
5198 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
5199 CFDictionaryRef config
;
5201 CFStringRef shared_id
;
5203 // get configuration
5204 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
5206 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
5208 config
= SCNetworkInterfaceGetConfiguration(interface
);
5211 // get sharedSecret ID
5212 shared_id
= copySharedSecretID(config
, serviceID
);
5215 (void) __extract_password(prefs
,
5217 kSCPropNetIPSecSharedSecret
,
5218 kSCPropNetIPSecSharedSecretEncryption
,
5219 kSCValNetIPSecSharedSecretEncryptionKeychain
,
5223 CFRelease(shared_id
);
5227 case kSCNetworkInterfacePasswordTypeEAPOL
: {
5228 CFDictionaryRef config
;
5229 CFStringRef unique_id
= NULL
;
5231 // get configuration
5232 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
5234 // get 802.1X identifier
5235 if (config
!= NULL
) {
5236 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
5238 if (!isA_CFString(unique_id
)) {
5239 _SCErrorSet(kSCStatusFailed
);
5244 password
= _SCPreferencesSystemKeychainPasswordItemCopy(prefs
, unique_id
);
5248 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
5249 CFDictionaryRef config
;
5250 CFStringRef xauth_id
;
5252 // get configuration
5253 config
= SCNetworkInterfaceGetConfiguration(interface
);
5256 xauth_id
= copyXAuthID(config
, serviceID
);
5259 (void) __extract_password(prefs
,
5261 kSCPropNetIPSecXAuthPassword
,
5262 kSCPropNetIPSecXAuthPasswordEncryption
,
5263 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
5266 CFRelease(xauth_id
);
5270 case kSCNetworkInterfacePasswordTypeVPN
: {
5271 CFDictionaryRef config
;
5274 // get configuration
5275 config
= SCNetworkInterfaceGetConfiguration(interface
);
5278 vpn_id
= getPasswordID(config
, serviceID
);
5281 (void) __extract_password(prefs
,
5283 kSCPropNetVPNAuthPassword
,
5284 kSCPropNetVPNAuthPasswordEncryption
,
5285 kSCValNetVPNAuthPasswordEncryptionKeychain
,
5292 _SCErrorSet(kSCStatusInvalidArgument
);
5301 SCNetworkInterfaceRemovePassword(SCNetworkInterfaceRef interface
,
5302 SCNetworkInterfacePasswordType passwordType
)
5305 SCPreferencesRef prefs
= NULL
;
5306 CFStringRef serviceID
= NULL
;
5308 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
5312 switch (passwordType
) {
5313 case kSCNetworkInterfacePasswordTypePPP
: {
5314 CFDictionaryRef config
;
5315 CFDictionaryRef newConfig
= NULL
;
5316 CFStringRef unique_id
;
5318 // get configuration
5319 config
= SCNetworkInterfaceGetConfiguration(interface
);
5322 unique_id
= getPasswordID(config
, serviceID
);
5325 ok
= __remove_password(prefs
,
5327 kSCPropNetPPPAuthPassword
,
5328 kSCPropNetPPPAuthPasswordEncryption
,
5329 kSCValNetPPPAuthPasswordEncryptionKeychain
,
5333 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
5334 if (newConfig
!= NULL
) CFRelease(newConfig
);
5340 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
5341 CFDictionaryRef config
;
5343 CFDictionaryRef newConfig
= NULL
;
5344 CFStringRef shared_id
;
5346 // get configuration
5347 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
5349 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
5351 config
= SCNetworkInterfaceGetConfiguration(interface
);
5354 // get sharedSecret ID
5355 shared_id
= copySharedSecretID(config
, serviceID
);
5358 ok
= __remove_password(prefs
,
5360 kSCPropNetIPSecSharedSecret
,
5361 kSCPropNetIPSecSharedSecretEncryption
,
5362 kSCValNetIPSecSharedSecretEncryptionKeychain
,
5367 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
5371 ok
= SCNetworkInterfaceSetConfiguration(interface
,
5374 if (newConfig
!= NULL
) CFRelease(newConfig
);
5377 CFRelease(shared_id
);
5381 case kSCNetworkInterfacePasswordTypeEAPOL
: {
5382 CFDictionaryRef config
;
5383 CFStringRef unique_id
= NULL
;
5385 // get configuration
5386 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
5388 // get 802.1X identifier
5389 if (config
!= NULL
) {
5390 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
5392 if (!isA_CFString(unique_id
)) {
5393 _SCErrorSet(kSCStatusFailed
);
5398 ok
= _SCPreferencesSystemKeychainPasswordItemRemove(prefs
, unique_id
);
5402 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
5403 CFDictionaryRef config
;
5404 CFDictionaryRef newConfig
= NULL
;
5405 CFStringRef xauth_id
;
5407 // get configuration
5408 config
= SCNetworkInterfaceGetConfiguration(interface
);
5411 xauth_id
= copyXAuthID(config
, serviceID
);
5414 ok
= __remove_password(prefs
,
5416 kSCPropNetIPSecXAuthPassword
,
5417 kSCPropNetIPSecXAuthPasswordEncryption
,
5418 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
5422 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
5423 if (newConfig
!= NULL
) CFRelease(newConfig
);
5426 CFRelease(xauth_id
);
5430 case kSCNetworkInterfacePasswordTypeVPN
: {
5431 CFDictionaryRef config
;
5432 CFDictionaryRef newConfig
= NULL
;
5435 // get configuration
5436 config
= SCNetworkInterfaceGetConfiguration(interface
);
5439 vpn_id
= getPasswordID(config
, serviceID
);
5442 ok
= __remove_password(prefs
,
5444 kSCPropNetVPNAuthPassword
,
5445 kSCPropNetVPNAuthPasswordEncryption
,
5446 kSCValNetVPNAuthPasswordEncryptionKeychain
,
5450 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
5451 if (newConfig
!= NULL
) CFRelease(newConfig
);
5457 _SCErrorSet(kSCStatusInvalidArgument
);
5466 SCNetworkInterfaceSetPassword(SCNetworkInterfaceRef interface
,
5467 SCNetworkInterfacePasswordType passwordType
,
5469 CFDictionaryRef options
)
5471 CFStringRef account
= NULL
;
5472 CFDictionaryRef config
;
5473 CFStringRef description
= NULL
;
5474 CFStringRef label
= NULL
;
5476 SCPreferencesRef prefs
= NULL
;
5477 CFStringRef serviceID
= NULL
;
5479 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
5483 switch (passwordType
) {
5484 case kSCNetworkInterfacePasswordTypePPP
: {
5485 SCNetworkServiceRef service
= NULL
;
5486 CFStringRef unique_id
;
5488 // get configuration
5489 config
= SCNetworkInterfaceGetConfiguration(interface
);
5492 unique_id
= getPasswordID(config
, serviceID
);
5494 // get "Account", "Name", "Kind"
5495 if (config
!= NULL
) {
5496 // auth name --> keychain "Account"
5497 account
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthName
);
5499 // PPP [user defined] "name" --> keychain "Name"
5500 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
5503 if (label
== NULL
) {
5504 // service name --> keychain "Name"
5505 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
5510 label
= SCNetworkServiceGetName(service
);
5511 if (label
== NULL
) {
5512 // interface name --> keychain "Name"
5513 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
5517 if (bundle
!= NULL
) {
5518 // "PPP Password" --> keychain "Kind"
5519 description
= CFBundleCopyLocalizedString(bundle
,
5520 CFSTR("KEYCHAIN_KIND_PPP_PASSWORD"),
5521 CFSTR("PPP Password"),
5526 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
5528 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
5529 (description
!= NULL
) ? description
: CFSTR("PPP Password"),
5534 CFMutableDictionaryRef newConfig
;
5536 if (config
!= NULL
) {
5537 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
5539 newConfig
= CFDictionaryCreateMutable(NULL
,
5541 &kCFTypeDictionaryKeyCallBacks
,
5542 &kCFTypeDictionaryValueCallBacks
);
5544 CFDictionarySetValue(newConfig
,
5545 kSCPropNetPPPAuthPassword
,
5547 CFDictionarySetValue(newConfig
,
5548 kSCPropNetPPPAuthPasswordEncryption
,
5549 kSCValNetPPPAuthPasswordEncryptionKeychain
);
5550 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
5551 CFRelease(newConfig
);
5554 if (description
!= NULL
) CFRelease(description
);
5555 if (service
!= NULL
) CFRelease(service
);
5559 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
5560 CFDictionaryRef baseConfig
= NULL
;
5562 SCNetworkServiceRef service
= NULL
;
5563 CFStringRef shared_id
;
5565 // get configuration
5566 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
5567 config
= SCNetworkInterfaceGetConfiguration(interface
);
5569 baseConfig
= config
;
5570 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
5573 // get sharedSecret ID
5574 shared_id
= copySharedSecretID(config
, serviceID
);
5576 // get "Account", "Name", "Kind"
5577 if (config
!= NULL
) {
5578 CFStringRef localIdentifier
;
5579 CFStringRef localIdentifierType
;
5581 if (CFDictionaryGetValueIfPresent(config
,
5582 kSCPropNetIPSecLocalIdentifierType
,
5583 (const void **)&localIdentifierType
)
5584 && CFEqual(localIdentifierType
, kSCValNetIPSecLocalIdentifierTypeKeyID
)
5585 && CFDictionaryGetValueIfPresent(config
,
5586 kSCPropNetIPSecLocalIdentifier
,
5587 (const void **)&localIdentifier
)
5588 && isA_CFString(localIdentifier
)) {
5589 // local identifier --> keychain "Account"
5590 account
= localIdentifier
;
5593 // PPP [user defined] "name" --> keychain "Name"
5595 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
5597 if (baseConfig
!= NULL
) {
5598 label
= CFDictionaryGetValue(baseConfig
, kSCPropUserDefinedName
);
5603 if (label
== NULL
) {
5604 // service name --> keychain "Name"
5605 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
5610 label
= SCNetworkServiceGetName(service
);
5611 if (label
== NULL
) {
5612 // interface name --> keychain "Name"
5613 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
5617 if (bundle
!= NULL
) {
5618 // "IPSec Shared Secret" --> keychain "Kind"
5619 description
= CFBundleCopyLocalizedString(bundle
,
5620 CFSTR("KEYCHAIN_KIND_IPSEC_SHARED_SECRET"),
5621 CFSTR("IPSec Shared Secret"),
5626 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
5628 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
5629 (description
!= NULL
) ? description
: CFSTR("IPSec Shared Secret"),
5634 CFMutableDictionaryRef newConfig
= NULL
;
5636 if (config
!= NULL
) {
5637 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
5639 newConfig
= CFDictionaryCreateMutable(NULL
,
5641 &kCFTypeDictionaryKeyCallBacks
,
5642 &kCFTypeDictionaryValueCallBacks
);
5644 CFDictionarySetValue(newConfig
,
5645 kSCPropNetIPSecSharedSecret
,
5647 CFDictionarySetValue(newConfig
,
5648 kSCPropNetIPSecSharedSecretEncryption
,
5649 kSCValNetIPSecSharedSecretEncryptionKeychain
);
5651 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
5655 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
5657 CFRelease(newConfig
);
5660 if (description
!= NULL
) CFRelease(description
);
5661 if (service
!= NULL
) CFRelease(service
);
5662 CFRelease(shared_id
);
5666 case kSCNetworkInterfacePasswordTypeEAPOL
: {
5667 CFStringRef account
= NULL
;
5668 CFStringRef unique_id
= NULL
;
5670 // get configuration
5671 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
5673 // get 802.1X identifier
5674 if (config
!= NULL
) {
5675 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
5676 unique_id
= isA_CFString(unique_id
);
5678 if (unique_id
!= NULL
) {
5679 CFRetain(unique_id
);
5683 uuid
= CFUUIDCreate(NULL
);
5684 unique_id
= CFUUIDCreateString(NULL
, uuid
);
5688 // 802.1x UserName --> keychain "Account"
5689 if (config
!= NULL
) {
5690 account
= CFDictionaryGetValue(config
, kEAPClientPropUserName
);
5693 // get "Name", "Kind"
5694 if (bundle
!= NULL
) {
5695 CFStringRef interface_name
;
5697 // "Network Connection (%@)" --> keychain "Name"
5698 interface_name
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
5699 if (interface_name
!= NULL
) {
5700 CFStringRef label_fmt
;
5702 label_fmt
= CFBundleCopyLocalizedString(bundle
,
5703 CFSTR("KEYCHAIN_DESCRIPTION_EAPOL_INTERFACE"),
5704 CFSTR("Network Connection (%@)"),
5706 label
= CFStringCreateWithFormat(NULL
, NULL
, label_fmt
, interface_name
);
5707 CFRelease(label_fmt
);
5709 label
= CFBundleCopyLocalizedString(bundle
,
5710 CFSTR("KEYCHAIN_DESCRIPTION_EAPOL"),
5711 CFSTR("Network Connection"),
5715 // "802.1X Password" --> keychain "Kind"
5716 description
= CFBundleCopyLocalizedString(bundle
,
5717 CFSTR("KEYCHAIN_KIND_EAPOL"),
5718 CFSTR("802.1X Password"),
5723 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
5725 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
5726 (description
!= NULL
) ? description
: CFSTR("802.1X Password"),
5731 CFMutableDictionaryRef newConfig
= NULL
;
5733 if (config
!= NULL
) {
5734 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
5736 newConfig
= CFDictionaryCreateMutable(NULL
,
5738 &kCFTypeDictionaryKeyCallBacks
,
5739 &kCFTypeDictionaryValueCallBacks
);
5741 CFDictionarySetValue(newConfig
,
5742 kEAPClientPropUserPasswordKeychainItemID
,
5744 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
5747 CFRelease(newConfig
);
5750 CFRelease(unique_id
);
5751 if (label
!= NULL
) CFRelease(label
);
5752 if (description
!= NULL
) CFRelease(description
);
5756 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
5757 SCNetworkServiceRef service
= NULL
;
5758 CFStringRef xauth_id
;
5760 // get configuration
5761 config
= SCNetworkInterfaceGetConfiguration(interface
);
5764 xauth_id
= copyXAuthID(config
, serviceID
);
5766 // get "Account", "Name", "Kind"
5767 if (config
!= NULL
) {
5768 // auth name --> keychain "Account"
5769 account
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthName
);
5771 // IPSec [user defined] "name" --> keychain "Name"
5772 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
5775 if (label
== NULL
) {
5776 // service name --> keychain "Name"
5777 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
5782 label
= SCNetworkServiceGetName(service
);
5783 if (label
== NULL
) {
5784 // interface name --> keychain "Name"
5785 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
5789 if (bundle
!= NULL
) {
5790 // "IPSec XAuth Password" --> keychain "Kind"
5791 description
= CFBundleCopyLocalizedString(bundle
,
5792 CFSTR("KEYCHAIN_KIND_IPSEC_XAUTH_PASSWORD"),
5793 CFSTR("IPSec XAuth Password"),
5798 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
5800 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
5801 (description
!= NULL
) ? description
: CFSTR("IPSec XAuth Password"),
5806 CFMutableDictionaryRef newConfig
;
5808 if (config
!= NULL
) {
5809 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
5811 newConfig
= CFDictionaryCreateMutable(NULL
,
5813 &kCFTypeDictionaryKeyCallBacks
,
5814 &kCFTypeDictionaryValueCallBacks
);
5816 CFDictionarySetValue(newConfig
,
5817 kSCPropNetIPSecXAuthPassword
,
5819 CFDictionarySetValue(newConfig
,
5820 kSCPropNetIPSecXAuthPasswordEncryption
,
5821 kSCValNetIPSecXAuthPasswordEncryptionKeychain
);
5822 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
5823 CFRelease(newConfig
);
5826 CFRelease(xauth_id
);
5827 if (description
!= NULL
) CFRelease(description
);
5828 if (service
!= NULL
) CFRelease(service
);
5832 case kSCNetworkInterfacePasswordTypeVPN
: {
5833 SCNetworkServiceRef service
= NULL
;
5836 // get configuration
5837 config
= SCNetworkInterfaceGetConfiguration(interface
);
5840 vpn_id
= getPasswordID(config
, serviceID
);
5842 // get "Account", "Name", "Kind"
5843 if (config
!= NULL
) {
5844 // auth name --> keychain "Account"
5845 account
= CFDictionaryGetValue(config
, kSCPropNetVPNAuthName
);
5847 // VPN [user defined] "name" --> keychain "Name"
5848 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
5851 if (label
== NULL
) {
5852 // service name --> keychain "Name"
5853 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
5858 label
= SCNetworkServiceGetName(service
);
5859 if (label
== NULL
) {
5860 // interface name --> keychain "Name"
5861 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
5865 if (bundle
!= NULL
) {
5866 // "VPN Password" --> keychain "Kind"
5867 description
= CFBundleCopyLocalizedString(bundle
,
5868 CFSTR("KEYCHAIN_KIND_VPN_PASSWORD"),
5869 CFSTR("VPN Password"),
5874 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
5876 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
5877 (description
!= NULL
) ? description
: CFSTR("VPN Password"),
5882 CFMutableDictionaryRef newConfig
;
5884 if (config
!= NULL
) {
5885 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
5887 newConfig
= CFDictionaryCreateMutable(NULL
,
5889 &kCFTypeDictionaryKeyCallBacks
,
5890 &kCFTypeDictionaryValueCallBacks
);
5892 CFDictionarySetValue(newConfig
,
5893 kSCPropNetVPNAuthPassword
,
5895 CFDictionarySetValue(newConfig
,
5896 kSCPropNetVPNAuthPasswordEncryption
,
5897 kSCValNetVPNAuthPasswordEncryptionKeychain
);
5898 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
5899 CFRelease(newConfig
);
5902 if (description
!= NULL
) CFRelease(description
);
5903 if (service
!= NULL
) CFRelease(service
);
5908 _SCErrorSet(kSCStatusInvalidArgument
);
5917 #pragma mark SCNetworkInterface [InterfaceNamer] SPIs
5921 _SCNetworkInterfaceCopyInterfaceInfo(SCNetworkInterfaceRef interface
)
5923 CFMutableDictionaryRef info
;
5924 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5927 info
= CFDictionaryCreateMutable(NULL
,
5929 &kCFTypeDictionaryKeyCallBacks
,
5930 &kCFTypeDictionaryValueCallBacks
);
5932 // add non-localized interface name
5933 name
= __SCNetworkInterfaceGetNonLocalizedDisplayName(interface
);
5935 CFDictionaryAddValue(info
, kSCPropUserDefinedName
, name
);
5939 if ((interfacePrivate
->usb
.vid
!= NULL
) || (interfacePrivate
->usb
.pid
!= NULL
)) {
5940 if (interfacePrivate
->usb
.name
!= NULL
) {
5941 CFDictionaryAddValue(info
, CFSTR(kUSBProductString
), interfacePrivate
->usb
.name
);
5943 if (interfacePrivate
->usb
.vid
!= NULL
) {
5944 CFDictionaryAddValue(info
, CFSTR(kUSBVendorID
), interfacePrivate
->usb
.vid
);
5946 if (interfacePrivate
->usb
.pid
!= NULL
) {
5947 CFDictionaryAddValue(info
, CFSTR(kUSBProductID
), interfacePrivate
->usb
.pid
);
5951 if (CFDictionaryGetCount(info
) == 0) {
5952 // do not return an empty dictionary
5961 SCNetworkInterfaceRef
5962 _SCNetworkInterfaceCreateWithIONetworkInterfaceObject(io_object_t if_obj
)
5964 SCNetworkInterfaceRef interface
= NULL
;
5966 /* initialize runtime */
5967 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5969 if (IOObjectConformsTo(if_obj
, kIONetworkInterfaceClass
)) {
5970 interface
= createInterface(if_obj
, processNetworkInterface
);
5971 } else if (IOObjectConformsTo(if_obj
, kIOSerialBSDServiceValue
)) {
5972 interface
= createInterface(if_obj
, processSerialInterface
);
5980 _SCNetworkInterfaceGetConfigurationAction(SCNetworkInterfaceRef interface
)
5982 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5984 return interfacePrivate
->configurationAction
;
5989 _SCNetworkInterfaceGetHardwareAddress(SCNetworkInterfaceRef interface
)
5991 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5993 return interfacePrivate
->address
;
5998 _SCNetworkInterfaceGetIOInterfaceType(SCNetworkInterfaceRef interface
)
6000 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6002 return interfacePrivate
->type
;
6007 _SCNetworkInterfaceGetIOInterfaceUnit(SCNetworkInterfaceRef interface
)
6009 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6011 return interfacePrivate
->unit
;
6016 _SCNetworkInterfaceGetIOPath(SCNetworkInterfaceRef interface
)
6018 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6020 return interfacePrivate
->path
;
6025 _SCNetworkInterfaceIsBuiltin(SCNetworkInterfaceRef interface
)
6027 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6029 return interfacePrivate
->builtin
;
6034 #pragma mark SCNetworkInterface SPIs
6038 _SCNetworkInterfaceCopySlashDevPath(SCNetworkInterfaceRef interface
)
6040 io_registry_entry_t device
;
6041 io_iterator_t device_iterator
= MACH_PORT_NULL
;
6042 CFStringRef device_path
= NULL
;
6043 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6045 CFStringRef match_keys
[2];
6046 CFTypeRef match_vals
[2];
6047 CFDictionaryRef match_dict
;
6048 CFDictionaryRef matching
;
6050 if (interfacePrivate
->entity_device
== NULL
) {
6054 if (interfacePrivate
->entity_device_unique
== NULL
) {
6058 match_keys
[0] = CFSTR(kIOTTYBaseNameKey
);
6059 match_vals
[0] = interfacePrivate
->entity_device
;
6060 match_dict
= CFDictionaryCreate(NULL
,
6061 (const void **)match_keys
,
6062 (const void **)match_vals
,
6064 &kCFTypeDictionaryKeyCallBacks
,
6065 &kCFTypeDictionaryValueCallBacks
);
6067 match_keys
[0] = CFSTR(kIOProviderClassKey
);
6068 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
6069 match_keys
[1] = CFSTR(kIOPropertyMatchKey
);
6070 match_vals
[1] = match_dict
;
6071 matching
= CFDictionaryCreate(NULL
,
6072 (const void **)match_keys
,
6073 (const void **)match_vals
,
6074 sizeof(match_keys
)/sizeof(match_keys
[0]),
6075 &kCFTypeDictionaryKeyCallBacks
,
6076 &kCFTypeDictionaryValueCallBacks
);
6077 CFRelease(match_dict
);
6079 // note: this "matching" dictionary will be consumed by the call to IOServiceGetMatchingServices
6080 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &device_iterator
);
6081 if (kr
!= kIOReturnSuccess
) {
6082 SCLog(TRUE
, LOG_DEBUG
, CFSTR("IOServiceGetMatchingServices() failed, kr = 0x%x"), kr
);
6086 while ((device_path
== NULL
) &&
6087 ((device
= IOIteratorNext(device_iterator
)) != MACH_PORT_NULL
)) {
6088 CFDictionaryRef overrides
;
6090 overrides
= IORegistryEntrySearchCFProperty(device
,
6092 kSCNetworkInterfaceNetworkConfigurationOverridesKey
,
6094 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
6095 if (overrides
!= NULL
) {
6096 CFDictionaryRef modemOverrides
;
6098 modemOverrides
= CFDictionaryGetValue(overrides
, kSCEntNetModem
);
6099 if (modemOverrides
!= NULL
) {
6100 CFRetain(modemOverrides
);
6102 CFRelease(overrides
);
6103 overrides
= modemOverrides
;
6105 if (overrides
== NULL
) {
6106 overrides
= IORegistryEntrySearchCFProperty(device
,
6108 CFSTR("DeviceModemOverrides"),
6110 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
6112 if (overrides
!= NULL
) {
6113 if (isA_CFDictionary(overrides
)) {
6114 CFStringRef matchIdentifier
;
6116 matchIdentifier
= CFDictionaryGetValue(overrides
, CFSTR("UniqueIdentifier"));
6117 if (isA_CFString(matchIdentifier
) &&
6118 CFEqual(interfacePrivate
->entity_device_unique
, matchIdentifier
)) {
6119 device_path
= IORegistryEntryCreateCFProperty(device
,
6120 CFSTR(kIOTTYDeviceKey
),
6125 CFRelease(overrides
);
6127 IOObjectRelease(device
);
6130 IOObjectRelease(device_iterator
);
6134 if (device_path
== NULL
) {
6135 // if we haven't found an exact match to our UniqueIdentifier
6136 // so we simply return the base name.
6137 device_path
= SCNetworkInterfaceGetBSDName(interface
);
6138 if (device_path
!= NULL
) {
6139 CFRetain(device_path
);
6148 _SCNetworkInterfaceIsBluetoothPAN(SCNetworkInterfaceRef interface
)
6150 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6152 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_GN
);
6157 _SCNetworkInterfaceIsBluetoothPAN_NAP(SCNetworkInterfaceRef interface
)
6159 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6161 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_NAP
);
6166 _SCNetworkInterfaceIsBluetoothP2P(SCNetworkInterfaceRef interface
)
6168 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6170 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_U
);
6175 _SCNetworkInterfaceIsHiddenConfiguration(SCNetworkInterfaceRef interface
)
6177 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6179 return interfacePrivate
->hidden
;
6184 _SCNetworkInterfaceIsModemV92(SCNetworkInterfaceRef interface
)
6186 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6188 return interfacePrivate
->modemIsV92
;
6193 _SCNetworkInterfaceIsTethered(SCNetworkInterfaceRef interface
)
6195 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6197 return (interfacePrivate
->sort_order
== kSortTethered
);
6202 #pragma mark SCNetworkInterface [internal] SPIs
6206 SCNetworkInterfacePrivateRef
6207 __SCNetworkInterfaceCreateCopy(CFAllocatorRef allocator
,
6208 SCNetworkInterfaceRef interface
,
6209 SCPreferencesRef prefs
,
6210 CFStringRef serviceID
)
6212 SCNetworkInterfacePrivateRef oldPrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6213 SCNetworkInterfacePrivateRef newPrivate
;
6215 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
6216 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
6218 if (interface
== kSCNetworkInterfaceIPv4
) {
6219 return (SCNetworkInterfacePrivateRef
)CFRetain(interface
);
6222 newPrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, prefs
, serviceID
, NULL
);
6223 newPrivate
->interface_type
= oldPrivate
->interface_type
;
6224 if (oldPrivate
->interface
!= NULL
) {
6225 newPrivate
->interface
= (SCNetworkInterfaceRef
)__SCNetworkInterfaceCreateCopy(NULL
, // allocator
6226 oldPrivate
->interface
, // interface
6227 prefs
, // [new] prefs
6228 serviceID
); // [new] serviceID
6230 if (oldPrivate
->name
!= NULL
) {
6231 newPrivate
->name
= CFRetain(oldPrivate
->name
);
6233 if (oldPrivate
->localized_name
!= NULL
) {
6234 newPrivate
->localized_name
= CFRetain(oldPrivate
->localized_name
);
6236 newPrivate
->localized_key
= oldPrivate
->localized_key
;
6237 if (oldPrivate
->localized_arg1
!= NULL
) {
6238 newPrivate
->localized_arg1
= CFRetain(oldPrivate
->localized_arg1
);
6240 if (oldPrivate
->localized_arg2
!= NULL
) {
6241 newPrivate
->localized_arg2
= CFRetain(oldPrivate
->localized_arg2
);
6243 if (oldPrivate
->unsaved
!= NULL
) {
6244 newPrivate
->unsaved
= CFDictionaryCreateMutableCopy(NULL
, 0, oldPrivate
->unsaved
);
6246 if (oldPrivate
->entity_device
!= NULL
) {
6247 newPrivate
->entity_device
= CFRetain(oldPrivate
->entity_device
);
6249 if (oldPrivate
->entity_device_unique
!= NULL
) {
6250 newPrivate
->entity_device_unique
= CFRetain(oldPrivate
->entity_device_unique
);
6252 newPrivate
->entity_type
= oldPrivate
->entity_type
;
6253 newPrivate
->entity_subtype
= oldPrivate
->entity_subtype
;
6254 if (oldPrivate
->supported_interface_types
!= NULL
) {
6255 newPrivate
->supported_interface_types
= CFArrayCreateMutableCopy(NULL
, 0, oldPrivate
->supported_interface_types
);
6257 if (oldPrivate
->supported_protocol_types
!= NULL
) {
6258 newPrivate
->supported_protocol_types
= CFArrayCreateMutableCopy(NULL
, 0, oldPrivate
->supported_protocol_types
);
6260 if (oldPrivate
->address
!= NULL
) {
6261 newPrivate
->address
= CFRetain(oldPrivate
->address
);
6263 newPrivate
->builtin
= oldPrivate
->builtin
;
6264 if (oldPrivate
->configurationAction
!= NULL
) {
6265 newPrivate
->configurationAction
= CFRetain(oldPrivate
->configurationAction
);
6267 newPrivate
->hidden
= oldPrivate
->hidden
;
6268 if (oldPrivate
->location
!= NULL
) {
6269 newPrivate
->location
= CFRetain(oldPrivate
->location
);
6271 if (oldPrivate
->path
!= NULL
) {
6272 newPrivate
->path
= CFRetain(oldPrivate
->path
);
6274 if (oldPrivate
->overrides
!= NULL
) {
6275 newPrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, oldPrivate
->overrides
);
6277 newPrivate
->modemIsV92
= oldPrivate
->modemIsV92
;
6278 if (oldPrivate
->type
!= NULL
) {
6279 newPrivate
->type
= CFRetain(oldPrivate
->type
);
6281 if (oldPrivate
->unit
!= NULL
) {
6282 newPrivate
->unit
= CFRetain(oldPrivate
->unit
);
6284 if (oldPrivate
->usb
.name
!= NULL
) {
6285 newPrivate
->usb
.name
= CFRetain(oldPrivate
->usb
.name
);
6287 if (oldPrivate
->usb
.vid
!= NULL
) {
6288 newPrivate
->usb
.vid
= CFRetain(oldPrivate
->usb
.vid
);
6290 if (oldPrivate
->usb
.pid
!= NULL
) {
6291 newPrivate
->usb
.pid
= CFRetain(oldPrivate
->usb
.pid
);
6293 newPrivate
->sort_order
= oldPrivate
->sort_order
;
6295 newPrivate
->supportsBond
= oldPrivate
->supportsBond
;
6296 if (oldPrivate
->bond
.interfaces
!= NULL
) {
6297 newPrivate
->bond
.interfaces
= CFRetain(oldPrivate
->bond
.interfaces
);
6299 if (oldPrivate
->bond
.mode
!= NULL
) {
6300 newPrivate
->bond
.mode
= CFRetain(oldPrivate
->bond
.mode
);
6302 if (oldPrivate
->bond
.options
!= NULL
) {
6303 newPrivate
->bond
.options
= CFRetain(oldPrivate
->bond
.options
);
6306 newPrivate
->supportsBridge
= oldPrivate
->supportsBridge
;
6307 if (oldPrivate
->bridge
.interfaces
!= NULL
) {
6308 newPrivate
->bridge
.interfaces
= CFRetain(oldPrivate
->bridge
.interfaces
);
6310 if (oldPrivate
->bridge
.options
!= NULL
) {
6311 newPrivate
->bridge
.options
= CFRetain(oldPrivate
->bridge
.options
);
6314 newPrivate
->supportsVLAN
= oldPrivate
->supportsVLAN
;
6315 if (oldPrivate
->vlan
.interface
!= NULL
) {
6316 newPrivate
->vlan
.interface
= CFRetain(oldPrivate
->vlan
.interface
);
6318 if (oldPrivate
->vlan
.tag
!= NULL
) {
6319 newPrivate
->vlan
.tag
= CFRetain(oldPrivate
->vlan
.tag
);
6321 if (oldPrivate
->vlan
.options
!= NULL
) {
6322 newPrivate
->vlan
.options
= CFRetain(oldPrivate
->vlan
.options
);
6331 __SCNetworkInterfaceCopyDeepConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
)
6333 CFMutableArrayRef configs
;
6335 configs
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
6337 while (interface
!= NULL
) {
6338 CFStringRef defaultType
;
6339 CFMutableDictionaryRef interfaceConfiguration
;
6341 interfaceConfiguration
= CFDictionaryCreateMutable(NULL
,
6343 &kCFTypeDictionaryKeyCallBacks
,
6344 &kCFTypeDictionaryValueCallBacks
);
6346 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
6347 if (defaultType
!= NULL
) {
6348 CFDictionaryRef config
;
6349 CFArrayRef extendedTypes
;
6352 config
= __SCNetworkInterfaceGetConfiguration(interface
, defaultType
);
6354 config
= __SCNetworkInterfaceGetDefaultConfiguration(set
, interface
);
6356 if (config
== NULL
) {
6357 config
= (CFDictionaryRef
)kCFNull
;
6359 CFDictionarySetValue(interfaceConfiguration
, defaultType
, config
);
6361 extendedTypes
= extendedConfigurationTypes(interface
);
6362 if (extendedTypes
!= NULL
) {
6366 n
= CFArrayGetCount(extendedTypes
);
6367 for (i
= 0; i
< n
; i
++) {
6368 CFStringRef extendedType
;
6370 extendedType
= CFArrayGetValueAtIndex(extendedTypes
, i
);
6371 config
= __SCNetworkInterfaceGetConfiguration(interface
, extendedType
);
6372 if (config
== NULL
) {
6373 config
= (CFDictionaryRef
)kCFNull
;
6375 CFDictionarySetValue(interfaceConfiguration
, extendedType
, config
);
6378 CFRelease(extendedTypes
);
6382 CFArrayAppendValue(configs
, interfaceConfiguration
);
6383 CFRelease(interfaceConfiguration
);
6385 interface
= SCNetworkInterfaceGetInterface(interface
);
6392 __private_extern__ Boolean
6393 __SCNetworkInterfaceIsMember(SCPreferencesRef prefs
, SCNetworkInterfaceRef interface
)
6395 CFArrayRef interfaces
;
6396 Boolean match
= FALSE
;
6397 CFMutableSetRef members
;
6399 members
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
6401 // add Bond [member] interfaces
6402 interfaces
= SCBondInterfaceCopyAll(prefs
);
6403 if (interfaces
!= NULL
) {
6404 __SCBondInterfaceListCollectMembers(interfaces
, members
);
6405 CFRelease(interfaces
);
6408 // add Bridge [member] interfaces
6409 interfaces
= SCBridgeInterfaceCopyAll(prefs
);
6410 if (interfaces
!= NULL
) {
6411 __SCBridgeInterfaceListCollectMembers(interfaces
, members
);
6412 CFRelease(interfaces
);
6415 if (CFSetGetCount(members
) == 0) {
6419 while (interface
!= NULL
) {
6420 match
= CFSetContainsValue(members
, interface
);
6422 // if the interface is a member of an
6423 // Ethernet Bond or Bridge
6427 interface
= SCNetworkInterfaceGetInterface(interface
);
6439 __SCNetworkInterfaceSetDeepConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
, CFArrayRef configs
)
6443 for (i
= 0; interface
!= NULL
; i
++) {
6444 CFStringRef defaultType
;
6445 CFDictionaryRef interfaceConfiguration
;
6447 interfaceConfiguration
= (configs
!= NULL
) ? CFArrayGetValueAtIndex(configs
, i
) : NULL
;
6449 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
6450 if (defaultType
!= NULL
) {
6451 CFDictionaryRef config
;
6452 CFArrayRef extendedTypes
;
6454 config
= (interfaceConfiguration
!= NULL
) ? CFDictionaryGetValue(interfaceConfiguration
, defaultType
)
6456 if (config
== (CFDictionaryRef
)kCFNull
) {
6460 // if service is not associated with the set
6461 if (!__SCNetworkInterfaceSetConfiguration(interface
, defaultType
, config
, TRUE
)) {
6462 SCLog(TRUE
, LOG_DEBUG
,
6463 CFSTR("__SCNetworkInterfaceSetDeepConfiguration __SCNetworkInterfaceSetConfiguration() failed, interface=%@, type=%@"),
6468 // apply default configuration to this set
6469 if (!__SCNetworkInterfaceSetDefaultConfiguration(set
, interface
, defaultType
, config
, TRUE
)) {
6470 SCLog(TRUE
, LOG_DEBUG
,
6471 CFSTR("__SCNetworkInterfaceSetDeepConfiguration __SCNetworkInterfaceSetDefaultConfiguration() failed, interface=%@, type=%@"),
6477 extendedTypes
= extendedConfigurationTypes(interface
);
6478 if (extendedTypes
!= NULL
) {
6482 n
= CFArrayGetCount(extendedTypes
);
6483 for (j
= 0; j
< n
; j
++) {
6484 CFStringRef extendedType
;
6486 extendedType
= CFArrayGetValueAtIndex(extendedTypes
, j
);
6487 config
= (interfaceConfiguration
!= NULL
) ? CFDictionaryGetValue(interfaceConfiguration
, extendedType
)
6489 if (config
== (CFDictionaryRef
)kCFNull
) {
6492 if (!__SCNetworkInterfaceSetConfiguration(interface
, extendedType
, config
, TRUE
)) {
6493 SCLog(TRUE
, LOG_DEBUG
,
6494 CFSTR("__SCNetworkInterfaceSetDeepConfiguration __SCNetworkInterfaceSetConfiguration() failed, interface=%@, type=%@"),
6500 CFRelease(extendedTypes
);
6504 interface
= SCNetworkInterfaceGetInterface(interface
);