2 * Copyright (c) 2004-2015 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 #if !TARGET_IPHONE_SIMULATOR
67 #include <IOKit/usb/IOUSBLib.h>
68 #endif // !TARGET_IPHONE_SIMULATOR
70 #include "dy_framework.h"
72 #ifndef kIODeviceSupportsHoldKey
73 #define kIODeviceSupportsHoldKey "V92Modem"
76 #ifndef kPCIThunderboltString
77 #define kPCIThunderboltString "PCI-Thunderbolt"
80 #ifndef kIOUserEthernetInterfaceRoleKey
81 #define kIOUserEthernetInterfaceRoleKey "InterfaceRole"
85 #include <mach/mach.h>
87 #include <net/if_types.h>
88 #include <net/if_dl.h>
89 #include <net/route.h>
90 #include <sys/ioctl.h>
91 #include <sys/param.h>
92 #include <sys/types.h>
93 #include <sys/socket.h>
95 #include <sys/sysctl.h>
98 #include <NSSystemDirectories.h>
101 static CFStringRef
copy_interface_string (CFBundleRef bundle
, CFStringRef key
, Boolean localized
);
102 static CFStringRef
__SCNetworkInterfaceCopyDescription (CFTypeRef cf
);
103 static CFStringRef
__SCNetworkInterfaceCopyFormattingDescription (CFTypeRef cf
, CFDictionaryRef formatOptions
);
104 static void __SCNetworkInterfaceDeallocate (CFTypeRef cf
);
105 static Boolean
__SCNetworkInterfaceEqual (CFTypeRef cf1
, CFTypeRef cf2
);
106 static CFHashCode
__SCNetworkInterfaceHash (CFTypeRef cf
);
125 kSortBluetoothPAN_GN
,
126 kSortBluetoothPAN_NAP
,
136 const CFStringRef kSCNetworkInterfaceType6to4
= CFSTR("6to4");
137 const CFStringRef kSCNetworkInterfaceTypeBluetooth
= CFSTR("Bluetooth");
138 const CFStringRef kSCNetworkInterfaceTypeBond
= CFSTR("Bond");
139 const CFStringRef kSCNetworkInterfaceTypeBridge
= CFSTR("Bridge");
140 const CFStringRef kSCNetworkInterfaceTypeEthernet
= CFSTR("Ethernet");
141 const CFStringRef kSCNetworkInterfaceTypeFireWire
= CFSTR("FireWire");
142 const CFStringRef kSCNetworkInterfaceTypeIEEE80211
= CFSTR("IEEE80211"); // IEEE 802.11, AirPort
143 const CFStringRef kSCNetworkInterfaceTypeIPSec
= CFSTR("IPSec");
144 const CFStringRef kSCNetworkInterfaceTypeIrDA
= CFSTR("IrDA");
145 const CFStringRef kSCNetworkInterfaceTypeL2TP
= CFSTR("L2TP");
146 const CFStringRef kSCNetworkInterfaceTypeLoopback
= CFSTR("Loopback");
147 const CFStringRef kSCNetworkInterfaceTypeModem
= CFSTR("Modem");
148 const CFStringRef kSCNetworkInterfaceTypePPP
= CFSTR("PPP");
149 const CFStringRef kSCNetworkInterfaceTypePPTP
= CFSTR("PPTP");
150 const CFStringRef kSCNetworkInterfaceTypeSerial
= CFSTR("Serial");
151 const CFStringRef kSCNetworkInterfaceTypeVLAN
= CFSTR("VLAN");
152 const CFStringRef kSCNetworkInterfaceTypeVPN
= CFSTR("VPN");
153 const CFStringRef kSCNetworkInterfaceTypeWWAN
= CFSTR("WWAN");
155 const CFStringRef kSCNetworkInterfaceTypeIPv4
= CFSTR("IPv4");
157 static SCNetworkInterfacePrivate __kSCNetworkInterfaceIPv4
= {
158 INIT_CFRUNTIME_BASE(), // cfBase
159 NULL
, // interface type
162 NULL
, // localized name
163 NULL
, // localization key
164 NULL
, // localization arg1
165 NULL
, // localization arg2
166 NULL
, // [layered] interface
171 NULL
, // entity_device
172 NULL
, // entity_device_unique
174 NULL
, // entity_subtype
175 NULL
, // supported_interface_types
176 NULL
, // supported_protocol_types
178 NULL
, // addressString
180 NULL
, // configurationAction
190 { NULL
, 0, 0 }, // usb { name, vid, pid }
191 kSortUnknown
, // sort_order
192 FALSE
, // supportsBond
193 { NULL
, NULL
, NULL
}, // bond { interfaces, mode, options }
194 FALSE
, // supportsBridge
195 { NULL
, NULL
}, // bridge { interfaces, options }
196 FALSE
, // supportsVLAN
197 { NULL
, NULL
, NULL
}, // vlan { interface, tag, options }
198 #if !TARGET_IPHONE_SIMULATOR
199 NULL
, // IPMonitorControl
200 #endif // !TARGET_IPHONE_SIMULATOR
203 const SCNetworkInterfaceRef kSCNetworkInterfaceIPv4
= (SCNetworkInterfaceRef
)&__kSCNetworkInterfaceIPv4
;
205 static SCNetworkInterfacePrivate __kSCNetworkInterfaceLoopback
= {
206 INIT_CFRUNTIME_BASE(), // cfBase
207 NULL
, // interface type
210 NULL
, // localized name
211 NULL
, // localization key
212 NULL
, // localization arg1
213 NULL
, // localization arg2
214 NULL
, // [layered] interface
219 NULL
, // entity_device
220 NULL
, // entity_device_unique
222 NULL
, // entity_subtype
223 NULL
, // supported_interface_types
224 NULL
, // supported_protocol_types
226 NULL
, // addressString
228 NULL
, // configurationAction
238 { NULL
, 0, 0 }, // usb { name, vid, pid }
239 kSortUnknown
, // sort_order
240 FALSE
, // supportsBond
241 { NULL
, NULL
, NULL
}, // bond { interfaces, mode, options }
242 FALSE
, // supportsBridge
243 { NULL
, NULL
}, // bridge { interfaces, options }
244 FALSE
, // supportsVLAN
245 { NULL
, NULL
, NULL
}, // vlan { interface, tag, options }
246 #if !TARGET_IPHONE_SIMULATOR
247 NULL
, // IPMonitorControl
248 #endif // !TARGET_IPHONE_SIMULATOR
251 const SCNetworkInterfaceRef kSCNetworkInterfaceLoopback
= (SCNetworkInterfaceRef
)&__kSCNetworkInterfaceLoopback
;
253 static CFMutableSetRef vendor_interface_types
= NULL
;
256 #pragma mark SCNetworkInterface configuration details
265 #define doOverIP do6to4|doL2TP|doPPTP|doIPSec
270 #define doProxies 1<<4
271 #if !TARGET_OS_IPHONE
273 #else // !TARGET_OS_IPHONE
275 #endif // !TARGET_OS_IPHONE
277 static const struct {
278 const CFStringRef
*interface_type
;
279 const CFStringRef
*entity_hardware
;
280 Boolean per_interface_config
;
281 uint32_t supported_interfaces
;
282 const CFStringRef
*ppp_subtype
;
283 uint32_t supported_protocols
;
284 } configurations
[] = {
285 // interface type entity_hardware if config? interface types PPP sub-type interface protocols
286 // ===================================== ==================== ========== =============== ======================================= =========================================
287 { &kSCNetworkInterfaceType6to4
, &kSCEntNet6to4
, FALSE
, doNone
, NULL
, doIPv6
},
288 { &kSCNetworkInterfaceTypeBluetooth
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
289 { &kSCNetworkInterfaceTypeBond
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
290 { &kSCNetworkInterfaceTypeBridge
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
291 { &kSCNetworkInterfaceTypeEthernet
, &kSCEntNetEthernet
, TRUE
, doPPP
, &kSCValNetInterfaceSubTypePPPoE
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
292 { &kSCNetworkInterfaceTypeFireWire
, &kSCEntNetFireWire
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
293 { &kSCNetworkInterfaceTypeIEEE80211
, &kSCEntNetAirPort
, TRUE
, doPPP
, &kSCValNetInterfaceSubTypePPPoE
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
294 { &kSCNetworkInterfaceTypeIPSec
, &kSCEntNetIPSec
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
295 { &kSCNetworkInterfaceTypeIrDA
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
296 { &kSCNetworkInterfaceTypeL2TP
, NULL
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypeL2TP
, doNone
},
297 { &kSCNetworkInterfaceTypeModem
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
298 { &kSCNetworkInterfaceTypePPP
, &kSCEntNetPPP
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
299 { &kSCNetworkInterfaceTypePPTP
, NULL
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPTP
, doNone
},
300 { &kSCNetworkInterfaceTypeSerial
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
301 { &kSCNetworkInterfaceTypeVLAN
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
302 { &kSCNetworkInterfaceTypeVPN
, &kSCEntNetVPN
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
303 { &kSCNetworkInterfaceTypeWWAN
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
304 // ===================================== =================== ========== =============== ======================================= =========================================
305 { &kSCNetworkInterfaceTypeLoopback
, NULL
, TRUE
, doNone
, NULL
, doIPv4
|doIPv6
},
306 // ===================================== =================== ========== =============== ======================================= =========================================
307 { &kSCNetworkInterfaceTypeIPv4
, NULL
, FALSE
, doOverIP
, NULL
, doNone
}
311 #define kSCNetworkInterfaceActive "Active"
312 #define kSCNetworkInterfaceInfo "SCNetworkInterfaceInfo"
313 #define kSCNetworkInterfaceType "SCNetworkInterfaceType"
314 #define kSCNetworkInterfaceBSDName kIOBSDNameKey
315 #define kSCNetworkInterfaceIOBuiltin kIOBuiltin
316 #define kSCNetworkInterfaceIOInterfaceNamePrefix kIOInterfaceNamePrefix
317 #define kSCNetworkInterfaceIOInterfaceType kIOInterfaceType
318 #define kSCNetworkInterfaceIOInterfaceUnit kIOInterfaceUnit
319 #define kSCNetworkInterfaceIOMACAddress kIOMACAddress
320 #define kSCNetworkInterfaceIOPathMatch kIOPathMatchKey
323 #define NETWORKINTERFACE_LOCALIZATIONS CFSTR("NetworkInterface")
324 static CFBundleRef bundle
= NULL
;
327 static CFTypeID __kSCNetworkInterfaceTypeID
= _kCFRuntimeNotATypeID
;
330 static const CFRuntimeClass __SCNetworkInterfaceClass
= {
332 "SCNetworkInterface", // className
335 __SCNetworkInterfaceDeallocate
, // dealloc
336 __SCNetworkInterfaceEqual
, // equal
337 __SCNetworkInterfaceHash
, // hash
338 __SCNetworkInterfaceCopyFormattingDescription
, // copyFormattingDesc
339 __SCNetworkInterfaceCopyDescription
// copyDebugDesc
343 static pthread_once_t initialized
= PTHREAD_ONCE_INIT
;
344 static pthread_once_t iokit_quiet
= PTHREAD_ONCE_INIT
;
347 static mach_port_t masterPort
= MACH_PORT_NULL
;
350 __SCNetworkInterfaceCopyDescription(CFTypeRef cf
)
352 return __SCNetworkInterfaceCopyFormattingDescription(cf
, NULL
);
356 __SCNetworkInterfaceCopyFormattingDescription(CFTypeRef cf
, CFDictionaryRef formatOptions
)
358 CFAllocatorRef allocator
= CFGetAllocator(cf
);
359 CFMutableStringRef result
;
360 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
362 result
= CFStringCreateMutable(allocator
, 0);
363 CFStringAppendFormat(result
, NULL
, CFSTR("<SCNetworkInterface %p [%p]> {"), cf
, allocator
);
364 CFStringAppendFormat(result
, NULL
, CFSTR("type = %@"), interfacePrivate
->interface_type
);
365 CFStringAppendFormat(result
, NULL
, CFSTR(", entity_device = %@"), interfacePrivate
->entity_device
);
366 if (interfacePrivate
->entity_device_unique
!= NULL
) {
367 CFStringAppendFormat(result
, NULL
, CFSTR("+%@"), interfacePrivate
->entity_device_unique
);
369 CFStringAppendFormat(result
, NULL
, CFSTR(", entity_type = %@"), interfacePrivate
->entity_type
);
370 if (interfacePrivate
->entity_subtype
!= NULL
) {
371 CFStringAppendFormat(result
, NULL
, CFSTR(" / %@"), interfacePrivate
->entity_subtype
);
373 if (interfacePrivate
->name
!= NULL
) {
374 CFStringAppendFormat(result
, NULL
, CFSTR(", name = %@"), interfacePrivate
->name
);
376 if (interfacePrivate
->localized_name
!= NULL
) {
377 CFStringAppendFormat(result
, NULL
, CFSTR(", name(l) = %@"), interfacePrivate
->localized_name
);
379 if (interfacePrivate
->localized_key
!= NULL
) {
380 CFStringAppendFormat(result
, NULL
, CFSTR(", name(k) = \"%@\""), interfacePrivate
->localized_key
);
381 if (interfacePrivate
->localized_arg1
!= NULL
) {
382 CFStringAppendFormat(result
, NULL
, CFSTR("+\"%@\""), interfacePrivate
->localized_arg1
);
384 if (interfacePrivate
->localized_arg2
!= NULL
) {
385 CFStringAppendFormat(result
, NULL
, CFSTR("+\"%@\""), interfacePrivate
->localized_arg2
);
389 if (interfacePrivate
->address
!= NULL
) {
394 CFStringAppendFormat(result
, NULL
, CFSTR(", address = "));
396 data
= CFDataGetBytePtr(interfacePrivate
->address
);
397 dataLen
= CFDataGetLength(interfacePrivate
->address
);
398 for (i
= 0; i
< dataLen
; i
++) {
399 CFStringAppendFormat(result
, NULL
, CFSTR("%s%02x"),
404 CFStringAppendFormat(result
, NULL
, CFSTR(", builtin = %s"), interfacePrivate
->builtin
? "TRUE" : "FALSE");
405 if (interfacePrivate
->hidden
) {
406 CFStringAppendFormat(result
, NULL
, CFSTR(", hidden = TRUE"));
408 if (interfacePrivate
->modemIsV92
) {
409 CFStringAppendFormat(result
, NULL
, CFSTR(", v.92"));
411 if (interfacePrivate
->location
!= NULL
) {
412 CFStringAppendFormat(result
, NULL
, CFSTR(", location = %@"), interfacePrivate
->location
);
414 if (interfacePrivate
->path
!= NULL
) {
415 CFStringAppendFormat(result
, NULL
, CFSTR(", path = %@"), interfacePrivate
->path
);
417 if (interfacePrivate
->entryID
!= 0) {
418 CFStringAppendFormat(result
, NULL
, CFSTR(", entryID = 0x%llx"), interfacePrivate
->entryID
);
420 if (interfacePrivate
->type
!= NULL
) {
421 CFStringAppendFormat(result
, NULL
, CFSTR(", type = %@"), interfacePrivate
->type
);
423 if (interfacePrivate
->unit
!= NULL
) {
424 CFStringAppendFormat(result
, NULL
, CFSTR(", unit = %@"), interfacePrivate
->unit
);
426 if ((interfacePrivate
->usb
.vid
!= NULL
) || (interfacePrivate
->usb
.pid
!= NULL
)) {
430 if (!isA_CFNumber(interfacePrivate
->usb
.pid
) ||
431 !CFNumberGetValue(interfacePrivate
->usb
.pid
, kCFNumberIntType
, &pid
)) {
434 if (!isA_CFNumber(interfacePrivate
->usb
.vid
) ||
435 !CFNumberGetValue(interfacePrivate
->usb
.vid
, kCFNumberIntType
, &vid
)) {
439 if (interfacePrivate
->usb
.name
!= NULL
) {
440 CFStringAppendFormat(result
, NULL
, CFSTR(", USB name = %@"),
441 interfacePrivate
->usb
.name
);
444 CFStringAppendFormat(result
, NULL
, CFSTR(", USB vid/pid = 0x%0x/0x%0x"),
448 if (interfacePrivate
->configurationAction
!= NULL
) {
449 CFStringAppendFormat(result
, NULL
, CFSTR(", action = %@"), interfacePrivate
->configurationAction
);
451 if (interfacePrivate
->overrides
!= NULL
) {
452 CFStringAppendFormat(result
, formatOptions
, CFSTR(", overrides = %p"), interfacePrivate
->overrides
);
454 CFStringAppendFormat(result
, NULL
, CFSTR(", order = %d"), interfacePrivate
->sort_order
);
455 if (interfacePrivate
->prefs
!= NULL
) {
456 CFStringAppendFormat(result
, NULL
, CFSTR(", prefs = %p"), interfacePrivate
->prefs
);
458 if (interfacePrivate
->serviceID
!= NULL
) {
459 CFStringAppendFormat(result
, NULL
, CFSTR(", service = %@"), interfacePrivate
->serviceID
);
461 if (interfacePrivate
->interface
!= NULL
) {
462 CFStringAppendFormat(result
, NULL
, CFSTR(", interface = %@"), interfacePrivate
->interface
);
464 if (interfacePrivate
->unsaved
!= NULL
) {
465 CFStringAppendFormat(result
, formatOptions
, CFSTR(", unsaved = %@"), interfacePrivate
->unsaved
);
468 if (interfacePrivate
->bond
.interfaces
!= NULL
) {
472 n
= CFArrayGetCount(interfacePrivate
->bond
.interfaces
);
473 for (i
= 0; i
< n
; i
++) {
474 SCNetworkInterfaceRef member
;
476 member
= CFArrayGetValueAtIndex(interfacePrivate
->bond
.interfaces
, i
);
477 CFStringAppendFormat(result
, NULL
,
479 (i
== 0) ? ", interfaces = " : ",",
480 SCNetworkInterfaceGetBSDName(member
));
483 if (interfacePrivate
->bond
.mode
!= NULL
) {
484 CFStringAppendFormat(result
, NULL
, CFSTR(", mode = %@"), interfacePrivate
->bond
.mode
);
486 if (interfacePrivate
->bond
.options
!= NULL
) {
489 str
= _SCCopyDescription(interfacePrivate
->bond
.options
, formatOptions
);
490 CFStringAppendFormat(result
, formatOptions
, CFSTR(", options = %@"), str
);
494 if (interfacePrivate
->bridge
.interfaces
!= NULL
) {
498 n
= CFArrayGetCount(interfacePrivate
->bridge
.interfaces
);
499 for (i
= 0; i
< n
; i
++) {
500 SCNetworkInterfaceRef member
;
502 member
= CFArrayGetValueAtIndex(interfacePrivate
->bridge
.interfaces
, i
);
503 CFStringAppendFormat(result
, NULL
,
505 (i
== 0) ? ", interfaces = " : ",",
506 SCNetworkInterfaceGetBSDName(member
));
509 if (interfacePrivate
->bridge
.options
!= NULL
) {
512 str
= _SCCopyDescription(interfacePrivate
->bridge
.options
, formatOptions
);
513 CFStringAppendFormat(result
, formatOptions
, CFSTR(", options = %@"), str
);
517 if (interfacePrivate
->vlan
.interface
!= NULL
) {
518 CFStringAppendFormat(result
, NULL
,
519 CFSTR(", interface = %@"),
520 SCNetworkInterfaceGetBSDName(interfacePrivate
->vlan
.interface
));
522 if (interfacePrivate
->vlan
.tag
!= NULL
) {
523 CFStringAppendFormat(result
, NULL
, CFSTR(", tag = %@"), interfacePrivate
->vlan
.tag
);
525 if (interfacePrivate
->vlan
.options
!= NULL
) {
528 str
= _SCCopyDescription(interfacePrivate
->vlan
.options
, formatOptions
);
529 CFStringAppendFormat(result
, formatOptions
, CFSTR(", options = %@"), str
);
533 CFStringAppendFormat(result
, NULL
, CFSTR("}"));
540 __SCNetworkInterfaceDeallocate(CFTypeRef cf
)
542 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
544 /* release resources */
546 if (interfacePrivate
->name
!= NULL
)
547 CFRelease(interfacePrivate
->name
);
549 if (interfacePrivate
->localized_name
!= NULL
)
550 CFRelease(interfacePrivate
->localized_name
);
552 if (interfacePrivate
->localized_arg1
!= NULL
)
553 CFRelease(interfacePrivate
->localized_arg1
);
555 if (interfacePrivate
->localized_arg2
!= NULL
)
556 CFRelease(interfacePrivate
->localized_arg2
);
558 if (interfacePrivate
->interface
!= NULL
)
559 CFRelease(interfacePrivate
->interface
);
561 if (interfacePrivate
->prefs
!= NULL
)
562 CFRelease(interfacePrivate
->prefs
);
564 if (interfacePrivate
->store
!= NULL
)
565 CFRelease(interfacePrivate
->store
);
567 if (interfacePrivate
->serviceID
!= NULL
)
568 CFRelease(interfacePrivate
->serviceID
);
570 if (interfacePrivate
->unsaved
!= NULL
)
571 CFRelease(interfacePrivate
->unsaved
);
573 if (interfacePrivate
->entity_device
!= NULL
)
574 CFRelease(interfacePrivate
->entity_device
);
576 if (interfacePrivate
->entity_device_unique
!= NULL
)
577 CFRelease(interfacePrivate
->entity_device_unique
);
579 if (interfacePrivate
->supported_interface_types
!= NULL
)
580 CFRelease(interfacePrivate
->supported_interface_types
);
582 if (interfacePrivate
->supported_protocol_types
!= NULL
)
583 CFRelease(interfacePrivate
->supported_protocol_types
);
585 if (interfacePrivate
->address
!= NULL
)
586 CFRelease(interfacePrivate
->address
);
588 if (interfacePrivate
->addressString
!= NULL
)
589 CFRelease(interfacePrivate
->addressString
);
591 if (interfacePrivate
->configurationAction
!= NULL
)
592 CFRelease(interfacePrivate
->configurationAction
);
594 if (interfacePrivate
->location
!= NULL
)
595 CFRelease(interfacePrivate
->location
);
597 if (interfacePrivate
->path
!= NULL
)
598 CFRelease(interfacePrivate
->path
);
600 if (interfacePrivate
->overrides
!= NULL
)
601 CFRelease(interfacePrivate
->overrides
);
603 if (interfacePrivate
->prefix
!= NULL
)
604 CFRelease(interfacePrivate
->prefix
);
606 if (interfacePrivate
->type
!= NULL
)
607 CFRelease(interfacePrivate
->type
);
609 if (interfacePrivate
->unit
!= NULL
)
610 CFRelease(interfacePrivate
->unit
);
612 if (interfacePrivate
->usb
.name
!= NULL
)
613 CFRelease(interfacePrivate
->usb
.name
);
615 if (interfacePrivate
->usb
.pid
!= NULL
)
616 CFRelease(interfacePrivate
->usb
.pid
);
618 if (interfacePrivate
->usb
.vid
!= NULL
)
619 CFRelease(interfacePrivate
->usb
.vid
);
621 if (interfacePrivate
->bond
.interfaces
!= NULL
)
622 CFRelease(interfacePrivate
->bond
.interfaces
);
624 if (interfacePrivate
->bond
.mode
!= NULL
)
625 CFRelease(interfacePrivate
->bond
.mode
);
627 if (interfacePrivate
->bond
.options
!= NULL
)
628 CFRelease(interfacePrivate
->bond
.options
);
630 if (interfacePrivate
->bridge
.interfaces
!= NULL
)
631 CFRelease(interfacePrivate
->bridge
.interfaces
);
633 if (interfacePrivate
->bridge
.options
!= NULL
)
634 CFRelease(interfacePrivate
->bridge
.options
);
636 if (interfacePrivate
->vlan
.interface
!= NULL
)
637 CFRelease(interfacePrivate
->vlan
.interface
);
639 if (interfacePrivate
->vlan
.tag
!= NULL
)
640 CFRelease(interfacePrivate
->vlan
.tag
);
642 if (interfacePrivate
->vlan
.options
!= NULL
)
643 CFRelease(interfacePrivate
->vlan
.options
);
644 #if !TARGET_IPHONE_SIMULATOR
645 if (interfacePrivate
->IPMonitorControl
!= NULL
)
646 CFRelease(interfacePrivate
->IPMonitorControl
);
647 #endif // !TARGET_IPHONE_SIMULATOR
653 __SCNetworkInterfaceEqual(CFTypeRef cf1
, CFTypeRef cf2
)
655 SCNetworkInterfacePrivateRef if1
= (SCNetworkInterfacePrivateRef
)cf1
;
656 SCNetworkInterfacePrivateRef if2
= (SCNetworkInterfacePrivateRef
)cf2
;
661 if (!CFEqual(if1
->interface_type
, if2
->interface_type
)) {
662 return FALSE
; // if not the same interface type
665 if (!_SC_CFEqual(if1
->entity_device
, if2
->entity_device
)) {
666 return FALSE
; // if not the same device
669 if ((if1
->entity_device_unique
!= NULL
) && (if2
->entity_device_unique
!= NULL
)) {
670 if (!_SC_CFEqual(if1
->entity_device_unique
, if2
->entity_device_unique
)) {
671 return FALSE
; // if not the same device unique identifier
673 } else if ((if1
->entity_device_unique
!= NULL
) || (if2
->entity_device_unique
!= NULL
)) {
677 name1
= __SCNetworkInterfaceGetNonLocalizedDisplayName((SCNetworkInterfaceRef
)if1
);
678 name2
= __SCNetworkInterfaceGetNonLocalizedDisplayName((SCNetworkInterfaceRef
)if2
);
679 if ((name1
!= NULL
) && (name2
!= NULL
) && !_SC_CFEqual(name1
, name2
)) {
680 return FALSE
; // if same device but not the same display name
684 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeBond
)) {
685 if (!_SC_CFEqual(if1
->bond
.interfaces
, if2
->bond
.interfaces
)) {
686 return FALSE
; // if not the same interfaces
688 if (!_SC_CFEqual(if1
->bond
.mode
, if2
->bond
.mode
)) {
689 return FALSE
; // if not the same mode
693 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeBridge
)) {
694 if (!_SC_CFEqual(if1
->bridge
.interfaces
, if2
->bridge
.interfaces
)) {
695 return FALSE
; // if not the same interfaces
699 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeVLAN
)) {
700 if (!_SC_CFEqual(if1
->vlan
.interface
, if2
->vlan
.interface
)) {
701 return FALSE
; // if not the same physical interface
703 if (!_SC_CFEqual(if1
->vlan
.tag
, if2
->vlan
.tag
)) {
704 return FALSE
; // if not the same tag
708 if (!_SC_CFEqual(if1
->interface
, if2
->interface
)) {
709 return FALSE
; // if not the same layering
717 __SCNetworkInterfaceHash(CFTypeRef cf
)
720 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
722 if (interfacePrivate
->entity_device
!= NULL
) {
723 if (interfacePrivate
->entity_device_unique
== NULL
) {
724 hash
= CFHash(interfacePrivate
->entity_device
);
728 str
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@+%@"),
729 interfacePrivate
->entity_device
,
730 interfacePrivate
->entity_device_unique
);
741 __SCNetworkInterfaceInitialize(void)
746 __kSCNetworkInterfaceTypeID
= _CFRuntimeRegisterClass(&__SCNetworkInterfaceClass
);
748 // initialize __kSCNetworkInterfaceIPv4
749 _CFRuntimeInitStaticInstance(&__kSCNetworkInterfaceIPv4
, __kSCNetworkInterfaceTypeID
);
750 __kSCNetworkInterfaceIPv4
.interface_type
= kSCNetworkInterfaceTypeIPv4
;
751 __kSCNetworkInterfaceIPv4
.localized_key
= CFSTR("ipv4");
753 // initialize __kSCNetworkInterfaceLoopback
754 _CFRuntimeInitStaticInstance(&__kSCNetworkInterfaceLoopback
, __kSCNetworkInterfaceTypeID
);
755 __kSCNetworkInterfaceLoopback
.interface_type
= kSCNetworkInterfaceTypeLoopback
;
756 __kSCNetworkInterfaceLoopback
.localized_key
= CFSTR("loopback");
757 __kSCNetworkInterfaceLoopback
.entity_device
= CFRetain(CFSTR("lo0"));
758 __kSCNetworkInterfaceLoopback
.entity_type
= kSCValNetInterfaceTypeLoopback
;
760 // get CFBundleRef for SystemConfiguration.framework
761 bundle
= _SC_CFBundleGet();
763 // get mach port used to communication with IOKit
764 kr
= IOMasterPort(MACH_PORT_NULL
, &masterPort
);
765 if (kr
!= kIOReturnSuccess
) {
766 SC_log(LOG_NOTICE
, "could not get IOMasterPort, kr = 0x%x", kr
);
774 SCNetworkInterfacePrivateRef
775 __SCNetworkInterfaceCreatePrivate(CFAllocatorRef allocator
,
776 SCNetworkInterfaceRef interface
,
777 SCPreferencesRef prefs
,
778 CFStringRef serviceID
)
780 SCNetworkInterfacePrivateRef interfacePrivate
;
783 /* initialize runtime */
784 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
786 /* allocate target */
787 size
= sizeof(SCNetworkInterfacePrivate
) - sizeof(CFRuntimeBase
);
788 interfacePrivate
= (SCNetworkInterfacePrivateRef
)_CFRuntimeCreateInstance(allocator
,
789 __kSCNetworkInterfaceTypeID
,
792 if (interfacePrivate
== NULL
) {
796 interfacePrivate
->interface_type
= NULL
;
797 interfacePrivate
->active
= FALSE
;
798 interfacePrivate
->name
= NULL
;
799 interfacePrivate
->localized_name
= NULL
;
800 interfacePrivate
->localized_key
= NULL
;
801 interfacePrivate
->localized_arg1
= NULL
;
802 interfacePrivate
->localized_arg2
= NULL
;
803 interfacePrivate
->interface
= (interface
!= NULL
) ? CFRetain(interface
) : NULL
;
804 interfacePrivate
->prefs
= (prefs
!= NULL
) ? CFRetain(prefs
) : NULL
;
805 interfacePrivate
->store
= NULL
;
806 interfacePrivate
->serviceID
= (serviceID
!= NULL
) ? CFRetain(serviceID
) : NULL
;
807 interfacePrivate
->unsaved
= NULL
;
808 interfacePrivate
->entity_device
= NULL
;
809 interfacePrivate
->entity_device_unique
= NULL
;
810 interfacePrivate
->entity_type
= NULL
;
811 interfacePrivate
->entity_subtype
= NULL
;
812 interfacePrivate
->supported_interface_types
= NULL
;
813 interfacePrivate
->supported_protocol_types
= NULL
;
814 interfacePrivate
->address
= NULL
;
815 interfacePrivate
->addressString
= NULL
;
816 interfacePrivate
->builtin
= FALSE
;
817 interfacePrivate
->configurationAction
= NULL
;
818 interfacePrivate
->hidden
= FALSE
;
819 interfacePrivate
->location
= NULL
;
820 interfacePrivate
->path
= NULL
;
821 interfacePrivate
->entryID
= 0;
822 interfacePrivate
->overrides
= NULL
;
823 interfacePrivate
->modemIsV92
= FALSE
;
824 interfacePrivate
->prefix
= NULL
;
825 interfacePrivate
->type
= NULL
;
826 interfacePrivate
->unit
= NULL
;
827 interfacePrivate
->usb
.name
= NULL
;
828 interfacePrivate
->usb
.vid
= NULL
;
829 interfacePrivate
->usb
.pid
= NULL
;
830 interfacePrivate
->sort_order
= kSortUnknown
;
832 interfacePrivate
->supportsBond
= FALSE
;
833 interfacePrivate
->bond
.interfaces
= NULL
;
834 interfacePrivate
->bond
.mode
= NULL
;
835 interfacePrivate
->bond
.options
= NULL
;
837 interfacePrivate
->supportsBridge
= FALSE
;
838 interfacePrivate
->bridge
.interfaces
= NULL
;
839 interfacePrivate
->bridge
.options
= NULL
;
841 interfacePrivate
->supportsVLAN
= FALSE
;
842 interfacePrivate
->vlan
.interface
= NULL
;
843 interfacePrivate
->vlan
.tag
= NULL
;
844 interfacePrivate
->vlan
.options
= NULL
;
846 return interfacePrivate
;
852 __SCNetworkInterfaceSupportsVLAN(CFStringRef bsd_if
)
856 struct if_msghdr
* ifm
;
857 char * if_name
= NULL
;
858 unsigned int if_index
;
860 Boolean vlanOK
= FALSE
;
862 // get the interface index
863 if_name
= _SC_cfstring_to_cstring(bsd_if
, NULL
, 0, kCFStringEncodingASCII
);
864 if (if_name
== NULL
) {
865 return FALSE
; // if conversion error
867 if_index
= if_nametoindex(if_name
);
869 goto done
; // if unknown interface
872 // get information for the specified interface
877 mib
[4] = NET_RT_IFLIST
;
878 mib
[5] = if_index
; /* ask for exactly one interface */
880 if (sysctl(mib
, 6, NULL
, &buf_len
, NULL
, 0) == -1) {
881 SC_log(LOG_NOTICE
, "sysctl() size failed: %s", strerror(errno
));
884 buf
= CFAllocatorAllocate(NULL
, buf_len
, 0);
885 if (sysctl(mib
, 6, buf
, &buf_len
, NULL
, 0) == -1) {
886 SC_log(LOG_NOTICE
, "sysctl() failed: %s", strerror(errno
));
890 // check the link type and hwassist flags
891 // ALIGN: buf is aligned
892 ifm
= (struct if_msghdr
*)(void *)buf
;
893 switch (ifm
->ifm_type
) {
895 #if defined(IF_HWASSIST_VLAN_TAGGING) && defined(IF_HWASSIST_VLAN_MTU)
896 struct if_data
*if_data
= &ifm
->ifm_data
;
898 if (if_data
->ifi_hwassist
& (IF_HWASSIST_VLAN_TAGGING
| IF_HWASSIST_VLAN_MTU
)) {
908 if (if_name
!= NULL
) CFAllocatorDeallocate(NULL
, if_name
);
909 if (buf
!= NULL
) CFAllocatorDeallocate(NULL
, buf
);
916 __SCCopyMacAddress(CFStringRef ifname
)
918 struct ifaddrs
*ifap
;
919 char ifname_c
[IFNAMSIZ
];
921 CFDataRef macAddress
= NULL
;
923 if(_SC_cfstring_to_cstring(ifname
,
926 kCFStringEncodingUTF8
) == NULL
) {
930 if (getifaddrs(&ifap
) == -1) {
932 SC_log(LOG_NOTICE
, "getifaddrs() failed: %s", strerror(errno
));
936 for (ifp
= ifap
; ifp
!= NULL
; ifp
= ifp
->ifa_next
) {
937 struct sockaddr_dl
*sdl
;
939 if(strcmp(ifname_c
, ifp
->ifa_name
) != 0) {
943 /* ALIGN: cast ok, this should be aligned (getifaddrs). */
944 sdl
= (struct sockaddr_dl
*)(void *)ifp
->ifa_addr
;
945 if (sdl
->sdl_family
!= AF_LINK
) {
949 macAddress
= CFDataCreate(NULL
, (UInt8
*)LLADDR(sdl
), sdl
->sdl_alen
);
958 SCNetworkInterfacePrivateRef
959 _SCBondInterfaceCreatePrivate(CFAllocatorRef allocator
,
962 SCNetworkInterfacePrivateRef interfacePrivate
;
964 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
);
965 if (interfacePrivate
== NULL
) {
969 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBond
;
970 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
971 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, bond_if
);
972 interfacePrivate
->address
= __SCCopyMacAddress(interfacePrivate
->entity_device
);
973 interfacePrivate
->builtin
= TRUE
;
974 interfacePrivate
->supportsVLAN
= __SCNetworkInterfaceSupportsVLAN(bond_if
);
975 interfacePrivate
->sort_order
= kSortBond
;
977 interfacePrivate
->localized_key
= CFSTR("bond");
978 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
980 interfacePrivate
->bond
.interfaces
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
981 // interfacePrivate->bond.mode = NULL;
982 // interfacePrivate->bond.options = NULL;
984 return interfacePrivate
;
989 SCNetworkInterfacePrivateRef
990 _SCBridgeInterfaceCreatePrivate(CFAllocatorRef allocator
,
991 CFStringRef bridge_if
)
993 SCNetworkInterfacePrivateRef interfacePrivate
;
995 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
);
996 if (interfacePrivate
== NULL
) {
1000 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBridge
;
1001 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1002 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, bridge_if
);
1003 interfacePrivate
->address
= __SCCopyMacAddress(interfacePrivate
->entity_device
);
1004 interfacePrivate
->builtin
= TRUE
;
1005 interfacePrivate
->supportsVLAN
= __SCNetworkInterfaceSupportsVLAN(bridge_if
);
1006 interfacePrivate
->sort_order
= kSortBridge
;
1008 interfacePrivate
->localized_key
= CFSTR("bridge");
1009 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
1011 interfacePrivate
->bridge
.interfaces
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
1012 // interfacePrivate->bridge.options = NULL;
1014 return interfacePrivate
;
1019 SCNetworkInterfacePrivateRef
1020 _SCVLANInterfaceCreatePrivate(CFAllocatorRef allocator
,
1021 CFStringRef vlan_if
)
1023 SCNetworkInterfacePrivateRef interfacePrivate
;
1025 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
);
1026 if (interfacePrivate
== NULL
) {
1030 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeVLAN
;
1031 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1032 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, vlan_if
);
1033 interfacePrivate
->address
= __SCCopyMacAddress(interfacePrivate
->entity_device
);
1034 interfacePrivate
->builtin
= TRUE
;
1035 interfacePrivate
->sort_order
= kSortVLAN
;
1037 interfacePrivate
->localized_key
= CFSTR("vlan");
1038 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
1040 // interfacePrivate->vlan.interface = NULL;
1041 // interfacePrivate->vlan.tag = NULL;
1042 // interfacePrivate->vlan.options = NULL;
1044 return interfacePrivate
;
1049 #pragma mark Interface ordering
1052 static CF_RETURNS_RETAINED CFArrayRef
1053 split_path(CFStringRef path
)
1055 CFArrayRef components
;
1056 CFMutableStringRef nPath
;
1058 // turn '@'s into '/'s
1059 nPath
= CFStringCreateMutableCopy(NULL
, 0, path
);
1060 (void) CFStringFindAndReplace(nPath
,
1063 CFRangeMake(0, CFStringGetLength(nPath
)),
1066 // split path into components to be compared
1067 components
= CFStringCreateArrayBySeparatingStrings(NULL
, nPath
, CFSTR("/"));
1075 _SCNetworkInterfaceCompare(const void *val1
, const void *val2
, void *context
)
1077 SCNetworkInterfacePrivateRef dev1
= (SCNetworkInterfacePrivateRef
)val1
;
1078 SCNetworkInterfacePrivateRef dev2
= (SCNetworkInterfacePrivateRef
)val2
;
1079 CFComparisonResult res
= kCFCompareEqualTo
;
1081 /* sort by interface type */
1082 if (dev1
->sort_order
!= dev2
->sort_order
) {
1083 if (dev1
->sort_order
< dev2
->sort_order
) {
1084 res
= kCFCompareLessThan
;
1086 res
= kCFCompareGreaterThan
;
1091 /* built-in interfaces sort first */
1092 if (dev1
->builtin
!= dev2
->builtin
) {
1093 if (dev1
->builtin
) {
1094 res
= kCFCompareLessThan
;
1096 res
= kCFCompareGreaterThan
;
1101 /* ... and then, sort built-in interfaces by "location" */
1102 if (dev1
->builtin
) {
1103 if (dev1
->location
!= dev2
->location
) {
1104 if (isA_CFString(dev1
->location
)) {
1105 if (isA_CFString(dev2
->location
)) {
1106 res
= CFStringCompare(dev1
->location
, dev2
->location
, 0);
1108 res
= kCFCompareLessThan
;
1111 res
= kCFCompareGreaterThan
;
1114 if (res
!= kCFCompareEqualTo
) {
1120 /* ... and, then sort by IOPathMatch */
1121 if ((dev1
->path
!= NULL
) && (dev2
->path
!= NULL
)) {
1122 CFArrayRef elements1
;
1123 CFArrayRef elements2
;
1129 elements1
= split_path(dev1
->path
);
1130 n1
= CFArrayGetCount(elements1
);
1132 elements2
= split_path(dev2
->path
);
1133 n2
= CFArrayGetCount(elements2
);
1135 n
= (n1
<= n2
) ? n1
: n2
;
1136 for (i
= 0; i
< n
; i
++) {
1145 e1
= CFArrayGetValueAtIndex(elements1
, i
);
1146 e2
= CFArrayGetValueAtIndex(elements2
, i
);
1148 str
= _SC_cfstring_to_cstring(e1
, NULL
, 0, kCFStringEncodingUTF8
);
1150 q1
= strtoq(str
, &end
, 16);
1151 isNum
= ((*str
!= '\0') && (*end
== '\0') && (errno
== 0));
1152 CFAllocatorDeallocate(NULL
, str
);
1155 // if e1 is a valid numeric string
1156 str
= _SC_cfstring_to_cstring(e2
, NULL
, 0, kCFStringEncodingUTF8
);
1158 q2
= strtoq(str
, &end
, 16);
1159 isNum
= ((*str
!= '\0') && (*end
== '\0') && (errno
== 0));
1160 CFAllocatorDeallocate(NULL
, str
);
1163 // if e2 is also a valid numeric string
1166 res
= kCFCompareEqualTo
;
1168 } else if (q1
< q2
) {
1169 res
= kCFCompareLessThan
;
1171 res
= kCFCompareGreaterThan
;
1177 res
= CFStringCompare(e1
, e2
, 0);
1178 if (res
!= kCFCompareEqualTo
) {
1183 if (res
== kCFCompareEqualTo
) {
1185 res
= kCFCompareLessThan
;
1186 } else if (n1
< n2
) {
1187 res
= kCFCompareGreaterThan
;
1191 CFRelease(elements1
);
1192 CFRelease(elements2
);
1194 if (res
!= kCFCompareEqualTo
) {
1199 /* ... and, then sort by BSD interface name */
1200 if ((dev1
->entity_device
!= NULL
) && (dev2
->entity_device
!= NULL
)) {
1201 res
= CFStringCompare(dev1
->entity_device
, dev2
->entity_device
, 0);
1202 if (res
!= kCFCompareEqualTo
) {
1207 /* ... and lastly, sort by BSD interface unique identifier */
1208 if ((dev1
->entity_device_unique
!= NULL
) && (dev2
->entity_device_unique
!= NULL
)) {
1209 res
= CFStringCompare(dev1
->entity_device_unique
, dev2
->entity_device_unique
, 0);
1210 // if (res != kCFCompareEqualTo) {
1220 sort_interfaces(CFMutableArrayRef all_interfaces
)
1224 n
= CFArrayGetCount(all_interfaces
);
1229 CFArraySortValues(all_interfaces
, CFRangeMake(0, n
), _SCNetworkInterfaceCompare
, NULL
);
1236 __SCNetworkInterfaceOrder(SCNetworkInterfaceRef interface
)
1238 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
1240 return interfacePrivate
->sort_order
;
1245 #pragma mark Interface details
1249 IOCopyCFStringValue(CFTypeRef ioVal
)
1251 if (isA_CFString(ioVal
)) {
1252 return CFStringCreateCopy(NULL
, ioVal
);
1255 if (isA_CFData(ioVal
)) {
1256 return CFStringCreateWithCString(NULL
,
1257 (const char *)CFDataGetBytePtr(ioVal
),
1258 kCFStringEncodingUTF8
);
1266 IODictionaryCopyBSDName(CFDictionaryRef io_dict
)
1268 CFStringRef if_bsdName
;
1269 CFStringRef if_prefix
;
1270 CFNumberRef if_unit
;
1272 if_bsdName
= CFDictionaryGetValue(io_dict
, CFSTR(kIOBSDNameKey
));
1273 if (if_bsdName
!= NULL
) {
1274 return IOCopyCFStringValue(if_bsdName
);
1277 // no BSD name, get interface prefix and unit
1278 if_prefix
= CFDictionaryGetValue(io_dict
, CFSTR(kIOInterfaceNamePrefix
));
1279 if_unit
= CFDictionaryGetValue(io_dict
, CFSTR(kIOInterfaceUnit
));
1280 if (isA_CFString(if_prefix
) && isA_CFNumber(if_unit
)) {
1281 // if both prefix and unit available, construct BSD name
1282 if_bsdName
= CFStringCreateWithFormat(NULL
,
1294 IODictionaryCopyCFStringValue(CFDictionaryRef io_dict
, CFStringRef io_key
)
1298 ioVal
= CFDictionaryGetValue(io_dict
, io_key
);
1299 return IOCopyCFStringValue(ioVal
);
1304 IOStringValueHasPrefix(CFTypeRef ioVal
, CFStringRef prefix
)
1306 Boolean match
= FALSE
;
1307 CFIndex prefixLen
= CFStringGetLength(prefix
);
1308 CFStringRef str
= NULL
;
1310 if (!isA_CFString(ioVal
)) {
1311 if (isA_CFData(ioVal
)) {
1312 str
= CFStringCreateWithCStringNoCopy(NULL
,
1313 (const char *)CFDataGetBytePtr(ioVal
),
1314 kCFStringEncodingUTF8
,
1322 if ((ioVal
!= NULL
) &&
1323 (CFStringGetLength(ioVal
) >= prefixLen
) &&
1324 (CFStringCompareWithOptions(ioVal
,
1326 CFRangeMake(0, prefixLen
),
1327 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
)) {
1331 if (str
!= NULL
) CFRelease(str
);
1336 static const struct {
1337 const CFStringRef name
;
1338 const CFStringRef slot
;
1339 } slot_mappings
[] = {
1341 { CFSTR("A1") , CFSTR("1") },
1342 { CFSTR("B1") , CFSTR("2") },
1343 { CFSTR("C1") , CFSTR("3") },
1345 // Blue&White G3, Yikes G4
1346 { CFSTR("J12"), CFSTR("1") },
1347 { CFSTR("J11"), CFSTR("2") },
1348 { CFSTR("J10"), CFSTR("3") },
1349 { CFSTR("J9"), CFSTR("4") },
1352 { CFSTR("A") , CFSTR("1") },
1353 { CFSTR("B") , CFSTR("2") },
1354 { CFSTR("C") , CFSTR("3") },
1355 { CFSTR("D") , CFSTR("4") },
1357 // Digital Audio G4 (and later models)
1358 { CFSTR("1") , CFSTR("1") },
1359 { CFSTR("2") , CFSTR("2") },
1360 { CFSTR("3") , CFSTR("3") },
1361 { CFSTR("4") , CFSTR("4") },
1362 { CFSTR("5") , CFSTR("5") }
1366 static const CFStringRef slot_prefixes
[] = {
1367 CFSTR("thunderbolt slot "),
1373 static CF_RETURNS_RETAINED CFStringRef
1374 pci_slot(io_registry_entry_t interface
, CFTypeRef
*pci_slot_name
)
1377 io_registry_entry_t parent
;
1378 CFMutableStringRef slot
;
1379 CFTypeRef slot_name
;
1382 if (pci_slot_name
!= NULL
) *pci_slot_name
= NULL
;
1384 slot_name
= IORegistryEntryCreateCFProperty(interface
, CFSTR("AAPL,slot-name"), NULL
, 0);
1385 if (slot_name
!= NULL
) {
1388 slot
= CFStringCreateMutable(NULL
, 0);
1389 if (isA_CFString(slot_name
)) {
1390 if (pci_slot_name
!= NULL
) *pci_slot_name
= CFStringCreateCopy(NULL
, slot_name
);
1391 CFStringAppend(slot
, slot_name
);
1392 } else if (isA_CFData(slot_name
)) {
1393 if (pci_slot_name
!= NULL
) *pci_slot_name
= CFDataCreateCopy(NULL
, slot_name
);
1394 CFStringAppendCString(slot
,
1395 (const char *)CFDataGetBytePtr(slot_name
),
1396 kCFStringEncodingUTF8
);
1399 for (i
= 0; i
< sizeof(slot_prefixes
)/sizeof(slot_prefixes
[0]); i
++) {
1402 len
= CFStringGetLength(slot_prefixes
[i
]);
1403 if (CFStringGetLength(slot
) > len
) {
1404 (void) CFStringFindAndReplace(slot
,
1407 CFRangeMake(0, len
),
1408 kCFCompareCaseInsensitive
|kCFCompareAnchored
);
1412 for (i
= 0; i
< sizeof(slot_mappings
)/sizeof(slot_mappings
[0]); i
++) {
1413 if (CFStringCompare(slot
,
1414 slot_mappings
[i
].name
,
1415 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
1417 slot
= (CFMutableStringRef
)CFRetain(slot_mappings
[i
].slot
);
1422 CFRelease(slot_name
);
1425 kr
= IORegistryEntryGetParentEntry(interface
, kIOServicePlane
, &parent
);
1427 case kIOReturnSuccess
: {
1428 CFTypeRef parent_pci_slot_name
= NULL
;
1429 CFStringRef parent_slot
;
1431 parent_slot
= pci_slot(parent
, &parent_pci_slot_name
);
1432 if (parent_slot
!= NULL
) {
1433 if (slot
!= NULL
) CFRelease(slot
);
1434 slot
= (CFMutableStringRef
)parent_slot
;
1436 if (pci_slot_name
!= NULL
) {
1437 if (*pci_slot_name
!= NULL
) CFRelease(*pci_slot_name
);
1438 *pci_slot_name
= parent_pci_slot_name
;
1440 CFRelease(parent_pci_slot_name
);
1444 IOObjectRelease(parent
);
1447 case kIOReturnNoDevice
:
1448 // if we have hit the root node
1451 SC_log(LOG_INFO
, "IORegistryEntryGetParentEntry() failed, kr = 0x%x", kr
);
1459 static CFComparisonResult
1460 compare_bsdNames(const void *val1
, const void *val2
, void *context
)
1462 CFStringRef bsd1
= (CFStringRef
)val1
;
1463 CFStringRef bsd2
= (CFStringRef
)val2
;
1465 return CFStringCompare(bsd1
, bsd2
, 0);
1469 static CF_RETURNS_RETAINED CFStringRef
1470 pci_port(CFTypeRef slot_name
, int ift
, CFStringRef bsdName
)
1473 CFStringRef port_name
= NULL
;
1474 CFMutableArrayRef port_names
;
1477 CFStringRef match_keys
[2];
1478 CFTypeRef match_vals
[2];
1479 CFDictionaryRef match_dict
;
1480 CFDictionaryRef matching
;
1481 io_registry_entry_t slot
;
1482 io_iterator_t slot_iterator
= MACH_PORT_NULL
;
1484 match_keys
[0] = CFSTR("AAPL,slot-name");
1485 match_vals
[0] = slot_name
;
1487 match_dict
= CFDictionaryCreate(NULL
,
1488 (const void **)match_keys
,
1489 (const void **)match_vals
,
1491 &kCFTypeDictionaryKeyCallBacks
,
1492 &kCFTypeDictionaryValueCallBacks
);
1494 match_keys
[0] = CFSTR(kIOProviderClassKey
);
1495 match_vals
[0] = CFSTR("IOPCIDevice");
1497 match_keys
[1] = CFSTR(kIOPropertyMatchKey
);
1498 match_vals
[1] = match_dict
;
1500 // note: the "matching" dictionary will be consumed by the following
1501 matching
= CFDictionaryCreate(NULL
,
1502 (const void **)match_keys
,
1503 (const void **)match_vals
,
1504 sizeof(match_keys
)/sizeof(match_keys
[0]),
1505 &kCFTypeDictionaryKeyCallBacks
,
1506 &kCFTypeDictionaryValueCallBacks
);
1507 CFRelease(match_dict
);
1509 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &slot_iterator
);
1510 if (kr
!= kIOReturnSuccess
) {
1511 SC_log(LOG_INFO
, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr
);
1512 return MACH_PORT_NULL
;
1515 port_names
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1517 while ((slot
= IOIteratorNext(slot_iterator
)) != MACH_PORT_NULL
) {
1518 io_registry_entry_t child
;
1519 io_iterator_t child_iterator
= MACH_PORT_NULL
;
1521 kr
= IORegistryEntryCreateIterator(slot
,
1523 kIORegistryIterateRecursively
,
1525 if (kr
!= kIOReturnSuccess
) {
1526 SC_log(LOG_INFO
, "IORegistryEntryCreateIterator() failed, kr = 0x%x", kr
);
1527 CFRelease(port_names
);
1528 return MACH_PORT_NULL
;
1531 while ((child
= IOIteratorNext(child_iterator
)) != MACH_PORT_NULL
) {
1532 if (IOObjectConformsTo(child
, kIONetworkInterfaceClass
)) {
1533 CFMutableDictionaryRef interface_dict
= NULL
;
1535 (void) IORegistryEntryCreateCFProperties(child
, &interface_dict
, NULL
, kNilOptions
);
1536 if (interface_dict
!= NULL
) {
1537 CFNumberRef child_if_type
;
1538 int child_ift
= ift
;
1540 child_if_type
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceType
));
1541 if (child_if_type
!= NULL
) {
1542 if (!isA_CFNumber(child_if_type
) ||
1543 !CFNumberGetValue(child_if_type
, kCFNumberIntType
, &child_ift
)) {
1544 // assume that it's a match
1549 if (ift
== child_ift
) {
1550 CFStringRef if_bsdName
;
1552 if_bsdName
= IODictionaryCopyBSDName(interface_dict
);
1553 if (if_bsdName
!= NULL
) {
1554 CFArrayAppendValue(port_names
, if_bsdName
);
1555 CFRelease(if_bsdName
);
1559 CFRelease(interface_dict
);
1562 IOObjectRelease(child
);
1564 IOObjectRelease(child_iterator
);
1565 IOObjectRelease(slot
);
1567 IOObjectRelease(slot_iterator
);
1569 n
= CFArrayGetCount(port_names
);
1571 CFArraySortValues(port_names
, CFRangeMake(0, n
), compare_bsdNames
, NULL
);
1572 n
= CFArrayGetFirstIndexOfValue(port_names
, CFRangeMake(0, n
), bsdName
);
1573 if (n
!= kCFNotFound
) {
1574 port_name
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%ld"), n
+ 1);
1578 CFRelease(port_names
);
1584 pci_slot_info(io_registry_entry_t interface
, int ift
, CFStringRef
*slot_name
, CFStringRef
*port_name
)
1586 CFStringRef bsd_name
= NULL
;
1587 CFMutableDictionaryRef interface_dict
= NULL
;
1589 CFTypeRef pci_slot_name
;
1594 (void) IORegistryEntryCreateCFProperties(interface
, &interface_dict
, NULL
, kNilOptions
);
1595 if (interface_dict
!= NULL
) {
1596 bsd_name
= IODictionaryCopyBSDName(interface_dict
);
1597 CFRelease(interface_dict
);
1600 if (bsd_name
== NULL
) {
1604 *slot_name
= pci_slot(interface
, &pci_slot_name
);
1605 if (*slot_name
!= NULL
) {
1606 if (pci_slot_name
!= NULL
) {
1607 *port_name
= pci_port(pci_slot_name
, ift
, bsd_name
);
1608 CFRelease(pci_slot_name
);
1613 CFRelease(bsd_name
);
1619 isBuiltin(io_registry_entry_t interface
)
1623 slot
= pci_slot(interface
, NULL
);
1625 // interfaces which have a "slot" are not built-in
1635 isBluetoothBuiltin(Boolean
*haveController
)
1637 Boolean builtin
= FALSE
;
1638 io_object_t hciController
;
1639 io_iterator_t iter
= MACH_PORT_NULL
;
1642 kr
= IOServiceGetMatchingServices(masterPort
,
1643 IOServiceMatching("IOBluetoothHCIController"),
1645 if ((kr
!= kIOReturnSuccess
) || (iter
== MACH_PORT_NULL
)) {
1646 if (kr
!= kIOReturnSuccess
) {
1647 SC_log(LOG_INFO
, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr
);
1649 *haveController
= FALSE
;
1652 *haveController
= TRUE
;
1654 hciController
= IOIteratorNext(iter
);
1655 IOObjectRelease(iter
);
1656 if(hciController
!= MACH_PORT_NULL
) {
1657 #if !TARGET_IPHONE_SIMULATOR
1658 CFNumberRef idVendor
;
1660 idVendor
= IORegistryEntryCreateCFProperty(hciController
, CFSTR(kUSBVendorID
), NULL
, 0);
1661 if (idVendor
!= NULL
) {
1664 if (isA_CFNumber(idVendor
) &&
1665 CFNumberGetValue(idVendor
, kCFNumberIntType
, &idVendorVal
) &&
1666 (idVendorVal
== kIOUSBVendorIDAppleComputer
)) {
1670 CFRelease(idVendor
);
1672 #endif // !TARGET_IPHONE_SIMULATOR
1674 IOObjectRelease(hciController
);
1682 isThunderbolt(io_registry_entry_t interface
)
1686 val
= IORegistryEntrySearchCFProperty(interface
,
1688 CFSTR(kPCIThunderboltString
),
1690 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1701 processUSBInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1702 io_registry_entry_t interface
,
1703 CFDictionaryRef interface_dict
,
1704 io_registry_entry_t controller
,
1705 CFDictionaryRef controller_dict
,
1706 io_registry_entry_t bus
,
1707 CFDictionaryRef bus_dict
)
1709 #if !TARGET_IPHONE_SIMULATOR
1711 interfacePrivate
->usb
.name
= IORegistryEntrySearchCFProperty(interface
,
1713 CFSTR(kUSBProductString
),
1715 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1716 interfacePrivate
->usb
.vid
= IORegistryEntrySearchCFProperty(interface
,
1718 CFSTR(kUSBVendorID
),
1720 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1721 interfacePrivate
->usb
.pid
= IORegistryEntrySearchCFProperty(interface
,
1723 CFSTR(kUSBProductID
),
1725 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1726 #endif // !TARGET_IPHONE_SIMULATOR
1733 update_interface_name(SCNetworkInterfacePrivateRef interfacePrivate
,
1734 io_registry_entry_t interface
,
1737 Boolean updated
= FALSE
;
1740 // check if a "Product Name" has been provided
1741 val
= IORegistryEntrySearchCFProperty(interface
,
1743 CFSTR(kIOPropertyProductNameKey
),
1745 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1746 if ((val
== NULL
) && useUSBInfo
&& (interfacePrivate
->usb
.name
!= NULL
)) {
1747 // else, use "USB Product Name" if available
1748 val
= CFRetain(interfacePrivate
->usb
.name
);
1751 CFStringRef productName
;
1753 productName
= IOCopyCFStringValue(val
);
1756 if (productName
!= NULL
) {
1757 if (CFStringGetLength(productName
) > 0) {
1758 // if we have a [somewhat reasonable?] product name
1759 if (interfacePrivate
->name
!= NULL
) {
1760 CFRelease(interfacePrivate
->name
);
1762 interfacePrivate
->name
= CFRetain(productName
);
1763 if (interfacePrivate
->localized_name
!= NULL
) {
1764 CFRelease(interfacePrivate
->localized_name
);
1765 interfacePrivate
->localized_name
= NULL
;
1767 if (bundle
!= NULL
) {
1768 interfacePrivate
->localized_name
= copy_interface_string(bundle
, productName
, TRUE
);
1774 CFRelease(productName
);
1783 #pragma mark Interface enumeration
1786 typedef Boolean (*processInterface
)(SCNetworkInterfacePrivateRef interfacePrivate
,
1787 io_registry_entry_t interface
,
1788 CFDictionaryRef interface_dict
,
1789 io_registry_entry_t controller
,
1790 CFDictionaryRef controller_dict
,
1791 io_registry_entry_t bus
,
1792 CFDictionaryRef bus_dict
);
1796 merge_override(SCNetworkInterfacePrivateRef interfacePrivate
,
1797 io_registry_entry_t interface
,
1798 CFStringRef override
)
1803 key
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("Device%@Overrides"), override
);
1804 val
= IORegistryEntrySearchCFProperty(interface
,
1808 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1811 if (isA_CFDictionary(val
)) {
1812 if (interfacePrivate
->overrides
== NULL
) {
1813 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
1815 &kCFTypeDictionaryKeyCallBacks
,
1816 &kCFTypeDictionaryValueCallBacks
);
1818 CFDictionarySetValue(interfacePrivate
->overrides
, override
, val
);
1827 #define BT_PAN_NAME "Bluetooth PAN"
1828 #define BT_PAN_MAC BT_PAN_NAME " (MAC)"
1831 processNetworkInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1832 io_registry_entry_t interface
,
1833 CFDictionaryRef interface_dict
,
1834 io_registry_entry_t controller
,
1835 CFDictionaryRef controller_dict
,
1836 io_registry_entry_t bus
,
1837 CFDictionaryRef bus_dict
)
1847 num
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceType
));
1848 if (isA_CFNumber(num
) &&
1849 CFNumberGetValue(num
, kCFNumberIntType
, &ift
)) {
1850 interfacePrivate
->type
= CFRetain(num
);
1852 SC_log(LOG_INFO
, "no interface type");
1860 if (IOObjectConformsTo(controller
, "IO80211Controller") ||
1861 IOObjectConformsTo(controller
, "AirPortPCI" ) ||
1862 IOObjectConformsTo(controller
, "AirPortDriver" )) {
1863 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
1864 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1865 interfacePrivate
->sort_order
= kSortAirPort
;
1866 } else if (IOObjectConformsTo(controller
, "AppleThunderboltIPPort")) {
1867 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1868 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1869 interfacePrivate
->sort_order
= kSortThunderbolt
;
1870 } else if (IOObjectConformsTo(controller
, "IOBluetoothBNEPDriver")) {
1871 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1872 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1873 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
1874 } else if (IOObjectConformsTo(controller
, "AppleUSBEthernetHost")) {
1875 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1876 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1877 interfacePrivate
->sort_order
= kSortTethered
;
1878 } else if (IOObjectConformsTo(controller
, "AppleUSBCDCECMData")) {
1879 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1880 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1881 interfacePrivate
->sort_order
= kSortWWANEthernet
;
1884 if (interfacePrivate
->interface_type
== NULL
) {
1885 val
= IORegistryEntrySearchCFProperty(interface
,
1887 CFSTR(kIOUserEthernetInterfaceRoleKey
),
1889 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1891 if (isA_CFString(val
)) {
1892 if (CFEqual(val
, CFSTR(BT_PAN_NAME
))) {
1893 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1894 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1895 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
1896 } else if (CFEqual(val
, CFSTR("Bluetooth PAN-NAP"))) {
1897 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1898 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1899 interfacePrivate
->sort_order
= kSortBluetoothPAN_NAP
;
1900 } else if (CFEqual(val
, CFSTR("Bluetooth P2P"))) {
1901 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1902 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1903 interfacePrivate
->sort_order
= kSortBluetoothPAN_U
;
1911 if (interfacePrivate
->interface_type
== NULL
) {
1912 str
= IODictionaryCopyCFStringValue(bus_dict
, CFSTR("name"));
1914 if (CFEqual(str
, CFSTR("radio"))) {
1915 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
; // ??
1916 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1917 interfacePrivate
->sort_order
= kSortOtherWireless
;
1924 if (interfacePrivate
->interface_type
== NULL
) {
1925 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1926 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1927 interfacePrivate
->sort_order
= kSortEthernet
;
1929 // BOND support only enabled for ethernet devices
1930 interfacePrivate
->supportsBond
= TRUE
;
1933 // enable Bridge support
1934 interfacePrivate
->supportsBridge
= TRUE
;
1937 val
= isA_CFBoolean(CFDictionaryGetValue(interface_dict
, CFSTR(kIOBuiltin
)));
1939 val
= isA_CFBoolean(CFDictionaryGetValue(interface_dict
, CFSTR(kIOPrimaryInterface
)));
1942 interfacePrivate
->builtin
= CFBooleanGetValue(val
);
1944 interfacePrivate
->builtin
= isBuiltin(interface
);
1947 if (!interfacePrivate
->builtin
&&
1948 CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
)) {
1949 // always treat AirPort interfaces as built-in
1950 interfacePrivate
->builtin
= TRUE
;
1954 interfacePrivate
->location
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOLocation
));
1955 if ((interfacePrivate
->location
!= NULL
) &&
1956 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1957 CFRelease(interfacePrivate
->location
);
1958 interfacePrivate
->location
= NULL
;
1962 num
= CFDictionaryGetValue(controller_dict
, CFSTR(kIOFeatures
));
1963 if (isA_CFNumber(num
) &&
1964 CFNumberGetValue(num
, kCFNumberIntType
, & iVal
)) {
1965 if (iVal
& (kIONetworkFeatureHardwareVlan
| kIONetworkFeatureSoftwareVlan
)) {
1966 interfacePrivate
->supportsVLAN
= TRUE
;
1971 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
)) {
1972 interfacePrivate
->localized_key
= CFSTR("airport");
1973 } else if (interfacePrivate
->sort_order
== kSortThunderbolt
) {
1974 if ((interfacePrivate
->location
== NULL
) ||
1975 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1976 interfacePrivate
->localized_key
= CFSTR("thunderbolt");
1978 interfacePrivate
->localized_key
= CFSTR("multithunderbolt");
1979 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->location
);
1981 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_GN
) {
1982 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-gn");
1983 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_NAP
) {
1984 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-nap");
1985 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_U
) {
1986 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-u");
1987 } else if (interfacePrivate
->sort_order
== kSortOtherWireless
) {
1988 interfacePrivate
->localized_key
= CFSTR("wireless");
1989 interfacePrivate
->localized_arg1
= CFRetain(CFSTR("")); // ??
1990 } else if (interfacePrivate
->builtin
) {
1991 if ((interfacePrivate
->location
== NULL
) ||
1992 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1993 interfacePrivate
->localized_key
= CFSTR("ether");
1995 interfacePrivate
->localized_key
= CFSTR("multiether");
1996 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->location
);
1999 CFStringRef provider
;
2001 // check provider class
2002 provider
= IORegistryEntrySearchCFProperty(interface
,
2004 CFSTR(kIOProviderClassKey
),
2006 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2007 if (provider
!= NULL
) {
2008 if (CFEqual(provider
, CFSTR("IOPCIDevice"))) {
2009 CFStringRef port_name
;
2010 CFStringRef slot_name
;
2012 // set interface "name"
2013 if (!update_interface_name(interfacePrivate
, interface
, FALSE
) &&
2014 pci_slot_info(interface
, ift
, &slot_name
, &port_name
)) {
2015 if (isThunderbolt(interface
)) {
2016 if (port_name
== NULL
) {
2017 interfacePrivate
->localized_key
= CFSTR("thunderbolt-ether");
2018 interfacePrivate
->localized_arg1
= slot_name
;
2020 interfacePrivate
->localized_key
= CFSTR("thunderbolt-multiether");
2021 interfacePrivate
->localized_arg1
= slot_name
;
2022 interfacePrivate
->localized_arg2
= port_name
;
2026 if (port_name
== NULL
) {
2027 interfacePrivate
->localized_key
= CFSTR("pci-ether");
2028 interfacePrivate
->localized_arg1
= slot_name
;
2030 interfacePrivate
->localized_key
= CFSTR("pci-multiether");
2031 interfacePrivate
->localized_arg1
= slot_name
;
2032 interfacePrivate
->localized_arg2
= port_name
;
2037 io_registry_entry_t node
= interface
;
2039 while (provider
!= NULL
) {
2040 #if !TARGET_IPHONE_SIMULATOR
2041 if (CFEqual(provider
, CFSTR(kIOUSBDeviceClassName
)) ||
2042 CFEqual(provider
, CFSTR(kIOUSBInterfaceClassName
))) {
2043 // get USB info (if available)
2044 processUSBInterface(interfacePrivate
,
2052 // set interface "name"
2053 if (!update_interface_name(interfacePrivate
, interface
, TRUE
)) {
2054 interfacePrivate
->localized_key
= CFSTR("usb-ether");
2055 interfacePrivate
->localized_arg1
= IODictionaryCopyBSDName(interface_dict
);
2059 #endif // !TARGET_IPHONE_SIMULATOR
2061 if (node
== interface
) {
2063 } else if (node
== controller
) {
2069 CFRelease(provider
);
2070 provider
= IORegistryEntrySearchCFProperty(node
,
2072 CFSTR(kIOProviderClassKey
),
2074 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2077 if (interfacePrivate
->localized_key
== NULL
) {
2078 update_interface_name(interfacePrivate
, interface
, FALSE
);
2082 if (provider
!= NULL
) CFRelease(provider
);
2085 if (interfacePrivate
->localized_key
== NULL
) {
2086 // if no provider, not a PCI device, or no slot information
2087 interfacePrivate
->localized_key
= CFSTR("generic-ether");
2088 interfacePrivate
->localized_arg1
= IODictionaryCopyBSDName(interface_dict
);
2095 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeFireWire
;
2098 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeFireWire
;
2101 interfacePrivate
->builtin
= isBuiltin(interface
);
2104 interfacePrivate
->sort_order
= kSortFireWire
;
2107 if (interfacePrivate
->builtin
) {
2108 interfacePrivate
->localized_key
= CFSTR("firewire");
2110 CFStringRef port_name
;
2111 CFStringRef slot_name
;
2113 // set interface "name"
2114 if (!update_interface_name(interfacePrivate
, interface
, FALSE
) &&
2115 pci_slot_info(interface
, ift
, &slot_name
, &port_name
)) {
2116 if (isThunderbolt(interface
)) {
2117 if (port_name
== NULL
) {
2118 interfacePrivate
->localized_key
= CFSTR("thunderbolt-firewire");
2119 interfacePrivate
->localized_arg1
= slot_name
;
2121 interfacePrivate
->localized_key
= CFSTR("thunderbolt-multifirewire");
2122 interfacePrivate
->localized_arg1
= slot_name
;
2123 interfacePrivate
->localized_arg2
= port_name
;
2126 if (port_name
== NULL
) {
2127 interfacePrivate
->localized_key
= CFSTR("pci-firewire");
2128 interfacePrivate
->localized_arg1
= slot_name
;
2130 interfacePrivate
->localized_key
= CFSTR("pci-multifirewire");
2131 interfacePrivate
->localized_arg1
= slot_name
;
2132 interfacePrivate
->localized_arg2
= port_name
;
2140 SC_log(LOG_INFO
, "unknown interface type = %d", ift
);
2145 interfacePrivate
->entity_device
= IODictionaryCopyBSDName(interface_dict
);
2147 // Hardware (MAC) address
2148 data
= CFDictionaryGetValue(controller_dict
, CFSTR(kIOMACAddress
));
2149 if (isA_CFData(data
)) {
2150 interfacePrivate
->address
= CFRetain(data
);
2154 str
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceNamePrefix
));
2155 if (isA_CFString(str
)) {
2156 interfacePrivate
->prefix
= CFRetain(str
);
2160 num
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceUnit
));
2161 if (isA_CFNumber(num
) &&
2162 CFNumberGetValue(num
, kCFNumberIntType
, & iVal
)) {
2163 interfacePrivate
->unit
= CFRetain(num
);
2166 // configuration [PPP] template override (now deprecated, use NetworkConfigurationOverrides)
2167 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypePPP
);
2174 set_connection_script(SCNetworkInterfacePrivateRef interfacePrivate
, CFStringRef script
)
2176 CFDictionaryRef dict
;
2177 CFMutableDictionaryRef newDict
;
2179 if (interfacePrivate
->overrides
== NULL
) {
2180 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
2182 &kCFTypeDictionaryKeyCallBacks
,
2183 &kCFTypeDictionaryValueCallBacks
);
2186 dict
= CFDictionaryGetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
2188 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
2190 newDict
= CFDictionaryCreateMutable(NULL
,
2192 &kCFTypeDictionaryKeyCallBacks
,
2193 &kCFTypeDictionaryValueCallBacks
);
2195 if (script
!= NULL
) {
2196 CFDictionarySetValue(newDict
, kSCPropNetModemConnectionScript
, script
);
2198 CFDictionaryRemoveValue(newDict
, kSCPropNetModemConnectionScript
);
2200 if (CFDictionaryGetCount(newDict
) > 0) {
2201 CFDictionarySetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
, newDict
);
2203 CFDictionaryRemoveValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
2207 if (CFDictionaryGetCount(interfacePrivate
->overrides
) == 0) {
2208 CFRelease(interfacePrivate
->overrides
);
2209 interfacePrivate
->overrides
= NULL
;
2216 is_valid_connection_script(CFStringRef script
)
2218 char ccl
[MAXPATHLEN
];
2219 char path
[MAXPATHLEN
];
2220 NSSearchPathEnumerationState state
;
2222 (void) _SC_cfstring_to_cstring(script
,
2225 kCFStringEncodingUTF8
);
2227 state
= NSStartSearchPathEnumeration(NSLibraryDirectory
,
2228 NSLocalDomainMask
|NSSystemDomainMask
);
2229 while ((state
= NSGetNextSearchPathEnumeration(state
, path
))) {
2231 struct stat statBuf
;
2233 if (ccl
[0] == '/') {
2234 path
[0] = '\0'; // if modemCCL is a full path
2236 strlcat(path
, "/Modem Scripts/", sizeof(path
));
2238 strlcat(path
, ccl
, sizeof(path
));
2240 if (stat(path
, &statBuf
) != 0) {
2241 if (errno
== ENOENT
) {
2245 SC_log(LOG_INFO
, "stat() failed: %s", strerror(errno
));
2248 if (S_ISREG(statBuf
.st_mode
)) {
2249 // if we have a valid CCL script
2253 #define BUNDLE_EXT ".ccl"
2254 #define BUNDLE_EXT_LEN sizeof(BUNDLE_EXT) - 1
2259 if ((n
<= BUNDLE_EXT_LEN
) ||
2260 (strstr(&path
[n
- BUNDLE_EXT_LEN
], BUNDLE_EXT
) == NULL
)) {
2261 strlcat(path
, BUNDLE_EXT
, sizeof(path
));
2262 if (stat(path
, &statBuf
) != 0) {
2263 if (errno
== ENOENT
) {
2267 SC_log(LOG_INFO
, "stat() failed: %s", strerror(errno
));
2271 if (S_ISDIR(statBuf
.st_mode
)) {
2272 // if we have a valid CCL bundle
2282 processSerialInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
2283 io_registry_entry_t interface
,
2284 CFDictionaryRef interface_dict
,
2285 io_registry_entry_t controller
,
2286 CFDictionaryRef controller_dict
,
2287 io_registry_entry_t bus
,
2288 CFDictionaryRef bus_dict
)
2290 CFStringRef base
= NULL
;
2292 Boolean isModem
= FALSE
;
2293 Boolean isWWAN
= FALSE
;
2294 CFStringRef modemCCL
= NULL
;
2298 // check if initializing
2299 val
= IORegistryEntrySearchCFProperty(interface
,
2301 kSCNetworkInterfaceInitializingKey
,
2303 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2305 Boolean initializing
;
2307 initializing
= isA_CFBoolean(val
) && CFBooleanGetValue(val
);
2310 return FALSE
; // if this interface is still initializing
2315 val
= IORegistryEntrySearchCFProperty(interface
,
2319 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2321 isWWAN
= isA_CFBoolean(val
) && CFBooleanGetValue(val
);
2326 interfacePrivate
->entity_device
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOTTYDeviceKey
));
2327 if (interfacePrivate
->entity_device
== NULL
) {
2331 base
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOTTYBaseNameKey
));
2333 base
= CFRetain(interfacePrivate
->entity_device
);
2339 * Exclude ports named "irda" because otherwise the IrDA ports on the
2340 * original iMac (rev's A through D) show up as serial ports. Given
2341 * that only the rev A actually had an IrDA port, and Mac OS X doesn't
2342 * even support it, these ports definitely shouldn't be listed.
2344 if (CFStringCompare(base
,
2346 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
2350 if (IOStringValueHasPrefix(base
, CFSTR("bluetooth"))) {
2351 Boolean haveController
= FALSE
;
2354 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBluetooth
;
2355 interfacePrivate
->sort_order
= kSortBluetooth
;
2356 interfacePrivate
->builtin
= isBluetoothBuiltin(&haveController
);
2357 if (!haveController
) {
2358 // if device with no controller present
2361 } else if (IOStringValueHasPrefix(base
, CFSTR("irda-ircomm"))) {
2363 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIrDA
;
2364 interfacePrivate
->sort_order
= kSortIrDA
;
2365 } else if (isWWAN
) {
2367 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeWWAN
;
2368 interfacePrivate
->sort_order
= kSortWWAN
;
2371 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeModem
;
2372 interfacePrivate
->sort_order
= kSortModem
;
2375 val
= IORegistryEntrySearchCFProperty(interface
,
2377 CFSTR(kIODeviceSupportsHoldKey
),
2379 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2383 if (isA_CFNumber(val
) &&
2384 CFNumberGetValue(val
, kCFNumberSInt32Type
, &v92
)) {
2385 interfacePrivate
->modemIsV92
= (v92
== 1);
2392 interfacePrivate
->entity_type
= kSCEntNetModem
;
2394 // Entity (Hardware)
2395 ift
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOSerialBSDTypeKey
));
2396 if (!isA_CFString(ift
)) {
2400 if (CFEqual(ift
, CFSTR(kIOSerialBSDModemType
))) {
2404 if (CFEqual(base
, CFSTR("modem"))) {
2405 interfacePrivate
->builtin
= TRUE
;
2406 interfacePrivate
->sort_order
= kSortInternalModem
;
2407 } else if (CFEqual(base
, CFSTR("usbmodem"))) {
2408 interfacePrivate
->sort_order
= kSortUSBModem
;
2410 } else if (CFEqual(ift
, CFSTR(kIOSerialBSDRS232Type
))) {
2412 interfacePrivate
->sort_order
= kSortSerialPort
;
2417 // configuration [PPP] template override (now deprecated, use NetworkConfigurationOverrides)
2418 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypePPP
);
2420 // configuration [Modem] template override (now deprecated, use NetworkConfigurationOverrides)
2421 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypeModem
);
2423 // look for modem CCL, unique identifier
2424 if (interfacePrivate
->overrides
!= NULL
) {
2425 val
= CFDictionaryGetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
2427 CFStringRef uniqueID
;
2429 modemCCL
= CFDictionaryGetValue(val
, kSCPropNetModemConnectionScript
);
2430 modemCCL
= isA_CFString(modemCCL
);
2432 uniqueID
= CFDictionaryGetValue(val
, CFSTR("UniqueIdentifier"));
2433 uniqueID
= isA_CFString(uniqueID
);
2434 if (uniqueID
!= NULL
) {
2435 // retain the device's base name and the unique id
2436 CFRelease(interfacePrivate
->entity_device
);
2437 interfacePrivate
->entity_device
= CFRetain(base
);
2438 interfacePrivate
->entity_device_unique
= CFStringCreateCopy(NULL
, uniqueID
);
2443 // if not part of the NetworkConfigurationOverrides/DeviceModemOverrides, look
2444 // a bit harder for the modem CCL
2445 if (modemCCL
== NULL
) {
2446 val
= IORegistryEntrySearchCFProperty(interface
,
2450 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2452 modemCCL
= IOCopyCFStringValue(val
);
2453 if (modemCCL
!= NULL
) {
2454 set_connection_script(interfacePrivate
, modemCCL
);
2455 CFRelease(modemCCL
);
2463 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIrDA
)) {
2464 interfacePrivate
->localized_key
= CFSTR("irda");
2465 } else if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBluetooth
)) {
2466 interfacePrivate
->localized_key
= CFSTR("bluetooth");
2468 CFStringRef localized
= NULL
;
2469 CFStringRef name
= NULL
;
2470 CFMutableStringRef port
;
2472 port
= CFStringCreateMutableCopy(NULL
, 0, base
);
2473 CFStringLowercase(port
, NULL
);
2476 CFStringAppend(port
, CFSTR("-port"));
2479 // set non-localized name
2480 if (bundle
!= NULL
) {
2481 name
= copy_interface_string(bundle
, port
, FALSE
);
2484 if (!CFEqual(port
, name
)) {
2485 // if [English] localization available
2486 interfacePrivate
->name
= name
;
2488 // if no [English] localization available, use TTY base name
2490 interfacePrivate
->name
= CFStringCreateCopy(NULL
, base
);
2493 interfacePrivate
->name
= CFStringCreateCopy(NULL
, base
);
2496 // set localized name
2497 if (bundle
!= NULL
) {
2498 localized
= copy_interface_string(bundle
, port
, TRUE
);
2500 if (localized
!= NULL
) {
2501 if (!CFEqual(port
, localized
)) {
2502 // if localization available
2503 interfacePrivate
->localized_name
= localized
;
2505 // if no localization available, use TTY base name
2506 CFRelease(localized
);
2507 interfacePrivate
->localized_name
= CFStringCreateCopy(NULL
, base
);
2510 interfacePrivate
->localized_name
= CFStringCreateCopy(NULL
, base
);
2513 if (!isModem
|| !CFEqual(base
, CFSTR("modem"))) {
2514 // get USB info (if available)
2515 processUSBInterface(interfacePrivate
,
2523 // set interface "name"
2524 if (update_interface_name(interfacePrivate
, interface
, TRUE
)) {
2525 // if "ModemCCL" not provided, also check if the product/interface
2526 // name matches a CCL script
2527 if ((modemCCL
== NULL
) &&
2528 is_valid_connection_script(interfacePrivate
->name
)) {
2529 set_connection_script(interfacePrivate
, interfacePrivate
->name
);
2541 if (!ok
&& (interfacePrivate
->entity_device
!= NULL
)) {
2542 CFRelease(interfacePrivate
->entity_device
);
2543 interfacePrivate
->entity_device
= NULL
;
2545 if (base
!= NULL
) CFRelease(base
);
2552 __SC_IORegistryEntryCopyPath(io_registry_entry_t entry
, const io_name_t plane
)
2555 * Create a path for a registry entry.
2559 CFStringRef str
= NULL
;
2561 status
= IORegistryEntryGetPath(entry
, plane
, path
);
2562 if (status
== kIOReturnSuccess
) {
2563 str
= CFStringCreateWithCString(NULL
, path
, kCFStringEncodingUTF8
);
2564 } else if (status
== kIOReturnBadArgument
) {
2565 io_registry_entry_t parent
;
2567 status
= IORegistryEntryGetParentEntry(entry
, plane
, &parent
);
2568 if (status
== kIOReturnSuccess
) {
2569 CFStringRef str_parent
;
2571 str_parent
= __SC_IORegistryEntryCopyPath(parent
, plane
);
2572 if (str_parent
!= NULL
) {
2575 status
= IORegistryEntryGetNameInPlane(entry
, plane
, name
);
2576 if (status
== kIOReturnSuccess
) {
2579 status
= IORegistryEntryGetLocationInPlane(entry
, plane
, location
);
2580 if (status
== kIOReturnSuccess
) {
2581 str
= CFStringCreateWithFormat(NULL
,
2588 str
= CFStringCreateWithFormat(NULL
,
2596 CFRelease(str_parent
);
2599 IOObjectRelease(parent
);
2606 static CFMutableDictionaryRef
2607 copyIORegistryProperties(io_registry_entry_t reg_ent
, const CFStringRef
*reg_keys
, CFIndex numKeys
)
2610 CFMutableDictionaryRef reg_dict
= NULL
;
2611 CFTypeRef value
= NULL
;
2613 reg_dict
= CFDictionaryCreateMutable(NULL
,
2615 &kCFTypeDictionaryKeyCallBacks
,
2616 &kCFTypeDictionaryValueCallBacks
);
2618 for (; idx
< numKeys
; idx
++) {
2619 value
= IORegistryEntryCreateCFProperty(reg_ent
, reg_keys
[idx
], NULL
, 0);
2620 if (value
!= NULL
) {
2621 CFDictionaryAddValue(reg_dict
, reg_keys
[idx
], value
);
2629 static SCNetworkInterfaceRef
2630 createInterface(io_registry_entry_t interface
, processInterface func
,
2631 CFStringRef hidden_key
)
2633 io_registry_entry_t bus
= MACH_PORT_NULL
;
2634 CFMutableDictionaryRef bus_dict
= NULL
;
2635 io_registry_entry_t controller
= MACH_PORT_NULL
;
2636 CFMutableDictionaryRef controller_dict
= NULL
;
2637 uint64_t entryID
= 0;
2638 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
2639 CFMutableDictionaryRef interface_dict
= NULL
;
2644 #if TARGET_IPHONE_SIMULATOR || 1 // while waiting for rdar://19431723
2646 const CFStringRef interface_dict_keys
[] = {
2647 CFSTR(kIOInterfaceType
),
2649 CFSTR(kIOBSDNameKey
),
2650 CFSTR(kIOPrimaryInterface
),
2651 CFSTR(kIOInterfaceNamePrefix
),
2652 CFSTR(kIOInterfaceUnit
),
2653 CFSTR(kIOTTYDeviceKey
),
2654 CFSTR(kIOTTYBaseNameKey
),
2655 CFSTR(kIOSerialBSDTypeKey
),
2658 #endif // !TARGET_IPHONE_SIMULATOR
2660 const CFStringRef controller_dict_keys
[] = {
2662 CFSTR(kIOMACAddress
)
2665 const CFStringRef bus_dict_keys
[] = {
2669 if (hidden_key
!= NULL
) {
2671 val
= IORegistryEntrySearchCFProperty(interface
,
2675 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2678 goto done
; // if this interface should not be exposed
2682 #if TARGET_IPHONE_SIMULATOR || 1 // while waiting for rdar://19431723
2683 // get the dictionary associated with the [interface] node
2684 kr
= IORegistryEntryCreateCFProperties(interface
, &interface_dict
, NULL
, kNilOptions
);
2685 if (kr
!= kIOReturnSuccess
) {
2686 SC_log(LOG_INFO
, "IORegistryEntryCreateCFProperties() failed, kr = 0x%x", kr
);
2690 interface_dict
= copyIORegistryProperties(interface
,
2691 interface_dict_keys
,
2692 sizeof(interface_dict_keys
)/sizeof(interface_dict_keys
[0]));
2693 #endif // !TARGET_IPHONE_SIMULATOR
2695 // get the controller node
2696 kr
= IORegistryEntryGetParentEntry(interface
, kIOServicePlane
, &controller
);
2697 if (kr
!= kIOReturnSuccess
) {
2698 SC_log(LOG_INFO
, "IORegistryEntryGetParentEntry() failed, kr = 0x%x", kr
);
2702 controller_dict
= copyIORegistryProperties(controller
,
2703 controller_dict_keys
,
2704 sizeof(controller_dict_keys
)/sizeof(controller_dict_keys
[0]));
2707 kr
= IORegistryEntryGetParentEntry(controller
, kIOServicePlane
, &bus
);
2708 if (kr
!= kIOReturnSuccess
) {
2709 SC_log(LOG_INFO
, "IORegistryEntryGetParentEntry() failed, kr = 0x%x", kr
);
2713 bus_dict
= copyIORegistryProperties(bus
,
2715 sizeof(bus_dict_keys
)/sizeof(bus_dict_keys
[0]));
2717 // get the registry entry ID
2718 kr
= IORegistryEntryGetRegistryEntryID(interface
, &entryID
);
2719 if (kr
!= kIOReturnSuccess
) {
2720 SC_log(LOG_INFO
, "IORegistryEntryGetRegistryEntryID() failed, kr = 0x%x", kr
);
2724 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
);
2725 assert(interfacePrivate
!= NULL
);
2726 interfacePrivate
->path
= __SC_IORegistryEntryCopyPath(interface
, kIOServicePlane
);
2727 interfacePrivate
->entryID
= entryID
;
2729 // configuration [PPP, Modem, DNS, IPv4, IPv6, Proxies, SMB] template overrides
2730 val
= IORegistryEntrySearchCFProperty(interface
,
2732 kSCNetworkInterfaceNetworkConfigurationOverridesKey
,
2734 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2736 if (isA_CFDictionary(val
)) {
2737 interfacePrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, val
);
2742 if ((*func
)(interfacePrivate
, interface
, interface_dict
, controller
, controller_dict
, bus
, bus_dict
)) {
2743 // get user-notification / auto-configuration preference
2744 val
= IORegistryEntrySearchCFProperty(interface
,
2746 kSCNetworkInterfaceConfigurationActionKey
,
2748 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2750 if (isA_CFString(val
)) {
2751 interfacePrivate
->configurationAction
= CFRetain(val
);
2756 // get HiddenConfiguration preference
2757 val
= IORegistryEntrySearchCFProperty(interface
,
2759 kSCNetworkInterfaceHiddenConfigurationKey
,
2761 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2763 interfacePrivate
->hidden
= TRUE
;
2767 CFRelease(interfacePrivate
);
2768 interfacePrivate
= NULL
;
2773 if (interface_dict
!= NULL
) CFRelease(interface_dict
);
2775 if (controller
!= MACH_PORT_NULL
) IOObjectRelease(controller
);
2776 if (controller_dict
!= NULL
) CFRelease(controller_dict
);
2778 if (bus
!= MACH_PORT_NULL
) IOObjectRelease(bus
);
2779 if (bus_dict
!= NULL
) CFRelease(bus_dict
);
2781 return (SCNetworkInterfaceRef
)interfacePrivate
;
2785 static CF_RETURNS_RETAINED CFArrayRef
2786 findMatchingInterfaces(CFDictionaryRef matching
, processInterface func
,
2787 CFStringRef hidden_key
)
2789 CFMutableArrayRef interfaces
;
2790 io_registry_entry_t interface
;
2792 io_iterator_t iterator
= MACH_PORT_NULL
;
2795 * A reference to the "matching" dictionary will be consumed by the
2796 * the call to IOServiceGetMatchingServices so we bump up the retain
2801 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &iterator
);
2802 if (kr
!= kIOReturnSuccess
) {
2803 SC_log(LOG_INFO
, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr
);
2807 interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2809 while ((interface
= IOIteratorNext(iterator
)) != MACH_PORT_NULL
) {
2810 SCNetworkInterfaceRef match
;
2812 match
= createInterface(interface
, func
, hidden_key
);
2813 if (match
!= NULL
) {
2814 CFArrayAppendValue(interfaces
, match
);
2818 IOObjectRelease(interface
);
2821 IOObjectRelease(iterator
);
2828 #pragma mark helper functions
2832 findConfiguration(CFStringRef interface_type
)
2836 for (i
= 0; i
< sizeof(configurations
)/sizeof(configurations
[0]); i
++) {
2837 if (CFEqual(interface_type
, *configurations
[i
].interface_type
)) {
2848 __SCNetworkInterfaceGetDefaultConfigurationType(SCNetworkInterfaceRef interface
)
2850 CFIndex interfaceIndex
;
2851 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2853 if (interfacePrivate
->serviceID
== NULL
) {
2854 // if not associated with a service (yet)
2855 _SCErrorSet(kSCStatusInvalidArgument
);
2859 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2860 if (interfaceIndex
== kCFNotFound
) {
2861 // unknown interface type, use per-service configuration preferences
2862 return interfacePrivate
->interface_type
; // entity
2865 if (configurations
[interfaceIndex
].entity_hardware
!= NULL
) {
2866 // if configuration information can be associated with this interface type
2867 return *configurations
[interfaceIndex
].entity_hardware
;
2870 _SCErrorSet(kSCStatusInvalidArgument
);
2877 __SCNetworkInterfaceIsValidExtendedConfigurationType(SCNetworkInterfaceRef interface
,
2878 CFStringRef extendedType
,
2879 Boolean requirePerInterface
)
2881 CFStringRef defaultType
;
2882 CFIndex extendedIndex
;
2883 CFIndex interfaceIndex
;
2884 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2885 Boolean isL2TP
= FALSE
;
2888 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
2889 if (defaultType
== NULL
) {
2893 if (CFEqual(extendedType
, defaultType
)) {
2894 // extended and default configuration types cannot conflict
2898 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2899 if (interfaceIndex
== kCFNotFound
) {
2900 // configuration information for unknown interface type's
2901 // are stored along with the service and we don't allow
2902 // per-service extended configurations
2906 if (CFEqual(extendedType
, kSCEntNetIPSec
)) {
2907 CFStringRef interfaceType
;
2909 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
2910 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
2911 SCNetworkInterfaceRef child
;
2913 child
= SCNetworkInterfaceGetInterface(interface
);
2914 if (child
!= NULL
) {
2915 interfaceType
= SCNetworkInterfaceGetInterfaceType(child
);
2916 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
2923 if (requirePerInterface
&&
2924 !configurations
[interfaceIndex
].per_interface_config
&&
2926 // we don't allow per-service extended configurations (except
2927 // that we do allow IPSec as an extended type for PPP->L2TP)
2931 extendedIndex
= findConfiguration(extendedType
);
2932 if ((extendedIndex
!= kCFNotFound
) && !isL2TP
) {
2933 // extended type cannot match a known interface type (except
2934 // that we do allow IPSec as an extended type for PPP->L2TP)
2940 * Do we match specific/known extended configuration types (e.g. EAPOL)
2941 * and ensure that any non-standard extended configuration types be of
2942 * the form com.myCompany.myType?
2951 _SCErrorSet(kSCStatusInvalidArgument
);
2958 CFStringRef defaultType
;
2959 CFMutableArrayRef types
;
2960 } extendedConfiguration
, *extendedConfigurationRef
;
2964 __addExtendedConfigurationType(const void *key
, const void *value
, void *context
)
2966 CFStringRef extendedType
= (CFStringRef
)key
;
2967 extendedConfigurationRef myContextRef
= (extendedConfigurationRef
)context
;
2969 if (CFEqual(extendedType
, myContextRef
->defaultType
)) {
2970 // do not include the default configuration type
2974 if (CFArrayContainsValue(myContextRef
->types
,
2975 CFRangeMake(0, CFArrayGetCount(myContextRef
->types
)),
2977 // if extendedType already has already been added
2981 CFArrayAppendValue(myContextRef
->types
, extendedType
);
2987 static CF_RETURNS_RETAINED CFArrayRef
2988 extendedConfigurationTypes(SCNetworkInterfaceRef interface
)
2991 CFIndex interfaceIndex
;
2992 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2993 extendedConfiguration myContext
;
2994 SCNetworkServiceRef service
;
2998 myContext
.defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
2999 if (myContext
.defaultType
== NULL
) {
3000 myContext
.types
= NULL
;
3004 myContext
.types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3006 if (interfacePrivate
->serviceID
== NULL
) {
3007 // if not associated with a service (yet)
3011 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
3012 if (interfaceIndex
== kCFNotFound
) {
3013 // we don't allow per-service extended configurations
3017 if (!configurations
[interfaceIndex
].per_interface_config
) {
3018 // known interface type but we still don't allow
3019 // per-service extended configurations
3023 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
3024 interfacePrivate
->prefs
,
3025 interfacePrivate
->serviceID
,
3028 sets
= SCNetworkSetCopyAll(interfacePrivate
->prefs
);
3029 n
= (sets
!= NULL
) ? CFArrayGetCount(sets
) : 0;
3031 for (i
= 0; i
< n
; i
++) {
3032 CFDictionaryRef configs
;
3035 CFArrayRef services
;
3036 SCNetworkSetRef set
;
3038 set
= CFArrayGetValueAtIndex(sets
, i
);
3039 services
= SCNetworkSetCopyServices(set
);
3040 found
= CFArrayContainsValue(services
,
3041 CFRangeMake(0, CFArrayGetCount(services
)),
3043 CFRelease(services
);
3049 // add stored extended configuration types
3050 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
3051 SCNetworkSetGetSetID(set
), // set
3052 interfacePrivate
->entity_device
, // service
3054 configs
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
3056 if (isA_CFDictionary(configs
)) {
3057 CFDictionaryApplyFunction(configs
,
3058 __addExtendedConfigurationType
,
3062 // add not-yet-stored extended configuration types
3063 if (interfacePrivate
->unsaved
!= NULL
) {
3064 CFDictionaryApplyFunction(interfacePrivate
->unsaved
,
3065 __addExtendedConfigurationType
,
3073 if (sets
!= NULL
) CFRelease(sets
);
3077 return myContext
.types
;
3081 stringCreateArray(CFStringRef str
)
3083 return (CFArrayCreate(NULL
, (const void **)&str
, 1, &kCFTypeArrayCallBacks
));
3087 copyPerInterfaceConfigurationPaths(SCNetworkInterfacePrivateRef interfacePrivate
,
3088 CFStringRef extendedType
)
3090 CFMutableArrayRef array
= NULL
;
3094 SCNetworkServiceRef service
;
3097 // known interface type, per-interface configuration preferences
3099 // 1. look for all sets which contain the associated service
3100 // 2. add a per-set path for the interface configuration for
3103 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
3104 interfacePrivate
->prefs
,
3105 interfacePrivate
->serviceID
,
3106 (SCNetworkInterfaceRef
)interfacePrivate
);
3108 sets
= SCNetworkSetCopyAll(interfacePrivate
->prefs
);
3109 n
= (sets
!= NULL
) ? CFArrayGetCount(sets
) : 0;
3111 for (i
= 0; i
< n
; i
++) {
3112 CFArrayRef services
;
3113 SCNetworkSetRef set
;
3115 set
= CFArrayGetValueAtIndex(sets
, i
);
3116 services
= SCNetworkSetCopyServices(set
);
3117 if (CFArrayContainsValue(services
,
3118 CFRangeMake(0, CFArrayGetCount(services
)),
3120 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
3121 SCNetworkSetGetSetID(set
), // set
3122 interfacePrivate
->entity_device
, // service
3123 extendedType
); // entity
3124 if (array
== NULL
) {
3125 array
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3127 CFArrayAppendValue(array
, path
);
3130 CFRelease(services
);
3134 if (sets
!= NULL
) CFRelease(sets
);
3140 copyConfigurationPaths(SCNetworkInterfacePrivateRef interfacePrivate
,
3141 CFStringRef extendedType
)
3144 CFIndex interfaceIndex
;
3147 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
3148 if (interfaceIndex
== kCFNotFound
) {
3149 // unknown interface type, use per-service configuration preferences
3150 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
3151 interfacePrivate
->serviceID
, // service
3152 extendedType
); // entity
3153 array
= stringCreateArray(path
);
3157 else if (!configurations
[interfaceIndex
].per_interface_config
) {
3158 // known interface type, per-service configuration preferences
3159 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
3160 interfacePrivate
->serviceID
, // service
3161 extendedType
); // entity
3162 array
= stringCreateArray(path
);
3166 array
= copyPerInterfaceConfigurationPaths(interfacePrivate
, extendedType
);
3173 #pragma mark SCNetworkInterface <--> preferences entity
3178 __SCNetworkInterfaceCopyInterfaceEntity(SCNetworkInterfaceRef interface
)
3180 CFMutableDictionaryRef entity
;
3181 CFIndex interfaceIndex
;
3182 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3184 entity
= CFDictionaryCreateMutable(NULL
,
3186 &kCFTypeDictionaryKeyCallBacks
,
3187 &kCFTypeDictionaryValueCallBacks
);
3188 if (interfacePrivate
->entity_type
!= NULL
) {
3189 CFDictionarySetValue(entity
,
3190 kSCPropNetInterfaceType
,
3191 interfacePrivate
->entity_type
);
3193 if (interfacePrivate
->entity_subtype
!= NULL
) {
3194 CFDictionarySetValue(entity
,
3195 kSCPropNetInterfaceSubType
,
3196 interfacePrivate
->entity_subtype
);
3198 if (interfacePrivate
->entity_device
!= NULL
) {
3199 CFDictionarySetValue(entity
,
3200 kSCPropNetInterfaceDeviceName
,
3201 interfacePrivate
->entity_device
);
3203 if (interfacePrivate
->entity_device_unique
!= NULL
) {
3204 CFDictionarySetValue(entity
,
3205 CFSTR("DeviceUniqueIdentifier"),
3206 interfacePrivate
->entity_device_unique
);
3208 if (interfacePrivate
->hidden
) {
3209 CFDictionarySetValue(entity
,
3210 kSCNetworkInterfaceHiddenConfigurationKey
,
3214 // match the "hardware" with the lowest layer
3216 SCNetworkInterfaceRef nextInterface
;
3218 nextInterface
= SCNetworkInterfaceGetInterface(interface
);
3219 if (nextInterface
== NULL
) {
3223 interface
= nextInterface
;
3225 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3227 if (CFEqual(interface
, kSCNetworkInterfaceIPv4
)) {
3231 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
3232 if (interfaceIndex
!= kCFNotFound
) {
3233 if (configurations
[interfaceIndex
].entity_hardware
!= NULL
) {
3234 CFDictionarySetValue(entity
,
3235 kSCPropNetInterfaceHardware
,
3236 *configurations
[interfaceIndex
].entity_hardware
);
3239 CFDictionarySetValue(entity
,
3240 kSCPropNetInterfaceHardware
,
3241 interfacePrivate
->interface_type
);
3244 // add the localized display name (which will only be used when/if the
3245 // interface is removed from the system)
3246 CFDictionarySetValue(entity
,
3247 kSCPropUserDefinedName
,
3248 SCNetworkInterfaceGetLocalizedDisplayName(interface
));
3250 // note that this is a V.92 capable modem
3251 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeModem
) &&
3252 interfacePrivate
->modemIsV92
) {
3256 num
= CFNumberCreate(NULL
, kCFNumberIntType
, &one
);
3257 CFDictionarySetValue(entity
,
3258 kSCPropNetInterfaceSupportsModemOnHold
,
3267 static SCNetworkInterfaceRef
3268 findInterface(CFArrayRef interfaces
, CFStringRef match_if
)
3273 n
= CFArrayGetCount(interfaces
);
3274 for (i
= 0; i
< n
; i
++) {
3275 SCNetworkInterfaceRef interface
= CFArrayGetValueAtIndex(interfaces
, i
);
3276 CFStringRef interfaceName
;
3278 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
3279 if ((interfaceName
!= NULL
) && CFEqual(interfaceName
, match_if
)) {
3280 CFRetain(interface
);
3288 #if !TARGET_OS_IPHONE
3289 static SCNetworkInterfaceRef
3290 findBondInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
3293 SCNetworkInterfaceRef interface
= NULL
;
3295 if (prefs
== NULL
) {
3299 // check if the interface is an Ethernet Bond
3300 bonds
= SCBondInterfaceCopyAll(prefs
);
3301 if (bonds
!= NULL
) {
3302 interface
= findInterface(bonds
, ifDevice
);
3307 #endif // !TARGET_OS_IPHONE
3309 static SCNetworkInterfaceRef
3310 findBridgeInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
3313 SCNetworkInterfaceRef interface
= NULL
;
3315 if (prefs
== NULL
) {
3319 // check if the interface is an bridge
3320 bridges
= SCBridgeInterfaceCopyAll(prefs
);
3321 if (bridges
!= NULL
) {
3322 interface
= findInterface(bridges
, ifDevice
);
3328 static SCNetworkInterfaceRef
3329 findVLANInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
3331 SCNetworkInterfaceRef interface
= NULL
;
3334 if (prefs
== NULL
) {
3338 // check if the interface is a VLAN
3339 vlans
= SCVLANInterfaceCopyAll(prefs
);
3340 if (vlans
!= NULL
) {
3341 interface
= findInterface(vlans
, ifDevice
);
3351 static CFMutableDictionaryRef
3352 copy_ppp_entity(CFStringRef bsdName
)
3354 CFMutableDictionaryRef entity
= NULL
;
3355 CFStringRef pattern
;
3356 CFMutableArrayRef patterns
;
3357 CFDictionaryRef dict
;
3359 patterns
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3360 pattern
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, kSCDynamicStoreDomainState
, kSCCompAnyRegex
, kSCEntNetPPP
);
3361 CFArrayAppendValue(patterns
, pattern
);
3363 pattern
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, kSCDynamicStoreDomainSetup
, kSCCompAnyRegex
, kSCEntNetInterface
);
3364 CFArrayAppendValue(patterns
, pattern
);
3366 dict
= SCDynamicStoreCopyMultiple(NULL
, NULL
, patterns
);
3367 CFRelease(patterns
);
3370 const void * keys_q
[N_QUICK
];
3371 const void ** keys
= keys_q
;
3373 const void * vals_q
[N_QUICK
];
3374 const void ** vals
= vals_q
;
3376 n
= CFDictionaryGetCount(dict
);
3377 if (n
> (CFIndex
)(sizeof(keys_q
) / sizeof(CFTypeRef
))) {
3378 keys
= CFAllocatorAllocate(NULL
, n
* sizeof(CFTypeRef
), 0);
3379 vals
= CFAllocatorAllocate(NULL
, n
* sizeof(CFTypeRef
), 0);
3381 CFDictionaryGetKeysAndValues(dict
, keys
, vals
);
3382 for (i
= 0; i
< n
; i
++) {
3383 CFArrayRef components
;
3384 CFStringRef interfaceKey
;
3385 CFDictionaryRef interfaceVal
;
3387 CFStringRef pppKey
= (CFStringRef
)keys
[i
];
3388 CFDictionaryRef pppVal
= (CFDictionaryRef
)vals
[i
];
3389 CFStringRef serviceID
;
3391 if (!CFStringHasSuffix(pppKey
, kSCEntNetPPP
) ||
3392 !CFDictionaryGetValueIfPresent(pppVal
, kSCPropInterfaceName
, (const void **)&ifName
) ||
3393 !CFEqual(bsdName
, ifName
)) {
3394 // if not matching PPP interface
3398 components
= CFStringCreateArrayBySeparatingStrings(NULL
, pppKey
, CFSTR("/"));
3399 serviceID
= CFArrayGetValueAtIndex(components
, 3);
3400 interfaceKey
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, kSCDynamicStoreDomainSetup
, serviceID
, kSCEntNetInterface
);
3401 interfaceVal
= CFDictionaryGetValue(dict
, interfaceKey
);
3402 CFRelease(interfaceKey
);
3403 CFRelease(components
);
3404 if (interfaceVal
!= NULL
) {
3405 entity
= CFDictionaryCreateMutableCopy(NULL
, 0, interfaceVal
);
3409 if (keys
!= keys_q
) {
3410 CFAllocatorDeallocate(NULL
, keys
);
3411 CFAllocatorDeallocate(NULL
, vals
);
3421 SCNetworkInterfaceRef
3422 _SCNetworkInterfaceCreateWithBSDName(CFAllocatorRef allocator
,
3423 CFStringRef bsdName
,
3426 CFMutableDictionaryRef entity
= NULL
;
3428 SCNetworkInterfaceRef interface
;
3430 bzero(&ifr
, sizeof(ifr
));
3431 if (_SC_cfstring_to_cstring(bsdName
, ifr
.ifr_name
, sizeof(ifr
.ifr_name
), kCFStringEncodingASCII
) != NULL
) {
3434 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
3436 if (ioctl(s
, SIOCGIFFLAGS
, (caddr_t
)&ifr
) == -1) {
3442 if ((ifr
.ifr_flags
& IFF_POINTOPOINT
) != 0) {
3444 entity
= copy_ppp_entity(bsdName
);
3448 if (entity
== NULL
) {
3449 entity
= CFDictionaryCreateMutable(NULL
,
3451 &kCFTypeDictionaryKeyCallBacks
,
3452 &kCFTypeDictionaryValueCallBacks
);
3453 CFDictionarySetValue(entity
, kSCPropNetInterfaceDeviceName
, bsdName
);
3456 #if !TARGET_OS_IPHONE
3457 if ((flags
& kIncludeBondInterfaces
) == 0) {
3458 CFDictionarySetValue(entity
, CFSTR("_NO_BOND_INTERFACES_"), kCFBooleanTrue
);
3460 #endif // !TARGET_OS_IPHONE
3462 if ((flags
& kIncludeBridgeInterfaces
) == 0) {
3463 CFDictionarySetValue(entity
, CFSTR("_NO_BRIDGE_INTERFACES_"), kCFBooleanTrue
);
3466 if ((flags
& kIncludeVLANInterfaces
) == 0) {
3467 CFDictionarySetValue(entity
, CFSTR("_NO_VLAN_INTERFACES_"), kCFBooleanTrue
);
3470 interface
= _SCNetworkInterfaceCreateWithEntity(NULL
, entity
, NULL
);
3478 _SCNetworkInterfaceCopyPrefixFromBSDName(CFStringRef bsdName
)
3480 CFMutableStringRef interfacePrefix
= NULL
;
3484 if (isA_CFString(bsdName
) == NULL
) {
3485 SC_log(LOG_DEBUG
, "no BSD name");
3489 interfacePrefix
= CFStringCreateMutableCopy(NULL
, 0, bsdName
);
3490 length
= CFStringGetLength(interfacePrefix
);
3492 while (length
> 0) {
3493 lastChar
= CFStringGetCharacterAtIndex(interfacePrefix
, length
- 1);
3494 if (lastChar
>= '0' && lastChar
<= '9') {
3495 CFStringDelete(interfacePrefix
,
3496 CFRangeMake(length
-1, 1));
3501 length
= CFStringGetLength(interfacePrefix
);
3504 return interfacePrefix
;
3509 __SCNetworkInterfaceSetIOInterfacePrefix(SCNetworkInterfaceRef interface
,
3510 CFStringRef prefix
);
3514 __SCNetworkInterfaceUpdateBSDName(SCNetworkInterfaceRef interface
, CFStringRef currentBSDName
, CFStringRef newBSDName
)
3516 Boolean success
= FALSE
;
3517 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3519 if (isA_SCNetworkInterface(interface
) == NULL
) {
3520 SC_log(LOG_INFO
, "No interface");
3524 if (CFEqual(currentBSDName
, newBSDName
)) {
3529 if (interfacePrivate
->entity_device
!= NULL
) {
3530 CFRelease(interfacePrivate
->entity_device
);
3532 interfacePrivate
->entity_device
= CFRetain(newBSDName
);
3540 __SCNetworkInterfaceUpdateIOPath(SCNetworkInterfaceRef interface
)
3542 Boolean success
= FALSE
;
3543 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3544 CFStringRef oldPath
= NULL
;
3545 CFStringRef newPath
= NULL
;
3547 // Using the BSD Name update the path
3548 oldPath
= interfacePrivate
->path
;
3549 if (isA_CFString(oldPath
) == NULL
) {
3552 newPath
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("Migrated_From: %@"), oldPath
);
3553 if (interfacePrivate
->path
!= NULL
) {
3554 CFRelease(interfacePrivate
->path
);
3556 interfacePrivate
->path
= CFRetain(newPath
);
3560 if (newPath
!= NULL
) {
3568 __SCNetworkInterfaceSetIOInterfacePrefix (SCNetworkInterfaceRef interface
,
3571 SCNetworkInterfacePrivateRef interfacePrivate
;
3573 if (isA_CFString(prefix
) == NULL
) {
3577 interfacePrivate
= (SCNetworkInterfacePrivateRef
) interface
;
3581 if (interfacePrivate
->prefix
!= NULL
) {
3582 CFRelease(interfacePrivate
->prefix
);
3585 interfacePrivate
->prefix
= prefix
;
3592 __SCNetworkInterfaceSetIOInterfaceUnit (SCNetworkInterfaceRef interface
,
3595 SCNetworkInterfacePrivateRef interfacePrivate
;
3596 CFStringRef newBSDName
= NULL
;
3597 CFStringRef oldBSDName
= NULL
;
3599 if (isA_CFNumber(unit
) == NULL
) {
3602 interfacePrivate
= (SCNetworkInterfacePrivateRef
) interface
;
3604 oldBSDName
= SCNetworkInterfaceGetBSDName(interface
);
3606 if (interfacePrivate
->prefix
== NULL
) {
3607 if (isA_CFString(interfacePrivate
->entity_device
) != NULL
) {
3608 CFStringRef interfaceNamePrefix
= _SCNetworkInterfaceCopyPrefixFromBSDName(interfacePrivate
->entity_device
);
3609 if (interfaceNamePrefix
== NULL
) {
3610 SC_log(LOG_INFO
, "interfaceNamePrefix is NULL");
3613 __SCNetworkInterfaceSetIOInterfacePrefix(interface
, interfaceNamePrefix
);
3614 CFRelease(interfaceNamePrefix
);
3619 if (interfacePrivate
->prefix
!= NULL
) {
3620 newBSDName
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@%@"), interfacePrivate
->prefix
, unit
);
3623 // Update the BSD Name
3624 if ((newBSDName
== NULL
) ||
3625 (__SCNetworkInterfaceUpdateBSDName(interface
, oldBSDName
, newBSDName
) == FALSE
)) {
3626 SC_log(LOG_INFO
, "BSD name update failed");
3630 if (__SCNetworkInterfaceUpdateIOPath(interface
) == FALSE
) {
3631 SC_log(LOG_INFO
, "IOPath update failed");
3635 if (interfacePrivate
->unit
!= NULL
) {
3636 CFRelease(interfacePrivate
->unit
);
3638 interfacePrivate
->unit
= unit
;
3641 if (newBSDName
!= NULL
) {
3642 CFRelease(newBSDName
);
3650 __SCNetworkInterfaceCopyStorageEntity(SCNetworkInterfaceRef interface
)
3652 CFMutableDictionaryRef interface_entity
= NULL
;
3653 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3654 CFBooleanRef active
= NULL
;
3655 CFStringRef bsdName
= NULL
;
3656 CFBooleanRef builtin
= NULL
;
3657 CFStringRef interfaceNamePrefix
= NULL
;
3658 CFNumberRef interfaceType
= NULL
;
3659 CFNumberRef interfaceUnit
= NULL
;
3660 CFDataRef macAddress
= NULL
;
3661 CFStringRef pathMatch
= NULL
;
3662 CFDictionaryRef info
= NULL
;
3663 CFStringRef type
= NULL
;
3665 if (interfacePrivate
->active
== TRUE
) {
3666 active
= kCFBooleanTrue
;
3669 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
3670 if (isA_CFString(bsdName
) == NULL
) {
3674 builtin
= interfacePrivate
->builtin
? kCFBooleanTrue
: kCFBooleanFalse
;
3675 interfaceNamePrefix
= _SCNetworkInterfaceGetIOInterfaceNamePrefix(interface
);
3676 if (isA_CFString(interfaceNamePrefix
) == NULL
) {
3680 interfaceType
= _SCNetworkInterfaceGetIOInterfaceType(interface
);
3681 if (isA_CFNumber(interfaceType
) == NULL
) {
3685 interfaceUnit
= _SCNetworkInterfaceGetIOInterfaceUnit(interface
);
3686 if (isA_CFNumber(interfaceUnit
) == NULL
) {
3690 macAddress
= _SCNetworkInterfaceGetHardwareAddress(interface
);
3691 if (isA_CFData(macAddress
) == NULL
) {
3695 pathMatch
= _SCNetworkInterfaceGetIOPath(interface
);
3696 if (isA_CFString(pathMatch
) == NULL
) {
3700 info
= _SCNetworkInterfaceCopyInterfaceInfo(interface
);
3701 if (isA_CFDictionary(info
) == NULL
) {
3705 type
= SCNetworkInterfaceGetInterfaceType(interface
);
3706 if (isA_CFString(type
) == NULL
) {
3710 interface_entity
= CFDictionaryCreateMutable(NULL
, 0,
3711 &kCFTypeDictionaryKeyCallBacks
,
3712 &kCFTypeDictionaryValueCallBacks
);
3714 if (isA_CFBoolean(active
) != NULL
) {
3715 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceActive
), active
);
3718 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceBSDName
), bsdName
);
3719 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOBuiltin
), builtin
);
3720 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceNamePrefix
), interfaceNamePrefix
);
3721 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceType
), interfaceType
);
3722 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceUnit
), interfaceUnit
);
3723 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOMACAddress
), macAddress
);
3724 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOPathMatch
), pathMatch
);
3725 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceInfo
), info
);
3726 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceType
), type
);
3731 return interface_entity
;
3736 __SCNetworkInterfaceSetService(SCNetworkInterfaceRef interface
,
3737 SCNetworkServiceRef service
)
3739 SCNetworkInterfacePrivateRef interfacePrivate
;
3740 SCNetworkServicePrivateRef servicePrivate
;
3742 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3743 if (interfacePrivate
->prefs
!= NULL
) {
3744 CFRelease(interfacePrivate
->prefs
);
3745 interfacePrivate
->prefs
= NULL
;
3747 if (interfacePrivate
->serviceID
!= NULL
) {
3748 CFRelease(interfacePrivate
->serviceID
);
3749 interfacePrivate
->serviceID
= NULL
;
3752 servicePrivate
= (SCNetworkServicePrivateRef
)service
;
3753 if (servicePrivate
->prefs
!= NULL
) {
3754 interfacePrivate
->prefs
= CFRetain(servicePrivate
->prefs
);
3756 if (servicePrivate
->serviceID
!= NULL
) {
3757 interfacePrivate
->serviceID
= CFRetain(servicePrivate
->serviceID
);
3766 __SCNetworkInterfaceMatchesName(CFStringRef name
, CFStringRef key
)
3771 if (bundle
== NULL
) {
3772 SC_log(LOG_NOTICE
, "%s: no bundle information to compare interface names", __FUNCTION__
);
3776 if (!isA_CFString(name
)) {
3777 // if no interface "name"
3781 // check non-localized name for a match
3782 str
= copy_interface_string(bundle
, key
, FALSE
);
3784 match
= CFEqual(name
, str
);
3791 // check localized name for a match
3792 str
= copy_interface_string(bundle
, key
, TRUE
);
3794 match
= CFEqual(name
, str
);
3805 #define kInterfaceTypeEthernetValue 6
3806 #define kInterfaceTypeFirewireValue 144
3809 static SCNetworkInterfaceRef
3810 __SCNetworkInterfaceCreateWithStorageEntity (CFAllocatorRef allocator
,
3811 CFDictionaryRef interface_entity
,
3812 SCPreferencesRef prefs
)
3814 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
3815 CFBooleanRef active
= NULL
;
3816 CFStringRef bsdName
= NULL
;
3817 CFBooleanRef ioBuiltin
= NULL
;
3818 CFStringRef ioInterfaceNamePrefix
= NULL
;
3819 CFNumberRef ioInterfaceType
= NULL
;
3820 int ioInterfaceTypeNum
;
3821 CFNumberRef ioInterfaceUnit
= NULL
;
3822 CFDataRef ioMACAddress
= NULL
;
3823 CFStringRef ioPathMatch
= NULL
;
3824 CFDictionaryRef SCNetworkInterfaceInfo
= NULL
;
3825 CFStringRef userDefinedName
= NULL
;
3826 CFStringRef usbProductName
= NULL
;
3827 CFNumberRef idProduct
= NULL
;
3828 CFNumberRef idVendor
= NULL
;
3829 CFStringRef type
= NULL
;
3831 /* initialize runtime */
3832 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
3834 if (isA_CFDictionary(interface_entity
) == NULL
) {
3835 SC_log(LOG_INFO
, "No interface entity");
3838 active
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceActive
));
3839 if (isA_CFBoolean(active
) == NULL
) {
3840 active
= kCFBooleanFalse
;
3842 bsdName
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceBSDName
));
3843 if (isA_CFString(bsdName
) == NULL
) {
3844 SC_log(LOG_INFO
, "No BSD name");
3847 ioBuiltin
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOBuiltin
));
3848 if (isA_CFBoolean(ioBuiltin
) == NULL
) {
3849 SC_log(LOG_INFO
, "No IOBuiltin property");
3852 ioInterfaceNamePrefix
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceNamePrefix
));
3853 if (isA_CFString(ioInterfaceNamePrefix
) == NULL
) {
3854 ioInterfaceNamePrefix
= _SCNetworkInterfaceCopyPrefixFromBSDName(bsdName
);
3855 if (ioInterfaceNamePrefix
== NULL
) {
3856 SC_log(LOG_INFO
, "No BSD interface name prefix");
3860 CFRetain(ioInterfaceNamePrefix
);
3862 ioInterfaceType
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceType
));
3863 if (isA_CFNumber(ioInterfaceType
) == NULL
) {
3864 SC_log(LOG_INFO
, "No IOInterfaceType");
3867 if (CFNumberGetValue(ioInterfaceType
, kCFNumberIntType
, &ioInterfaceTypeNum
) == FALSE
) {
3868 SC_log(LOG_NOTICE
, "Count not extract value from ioInterfaceType");
3870 ioInterfaceUnit
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceUnit
));
3871 if (isA_CFNumber(ioInterfaceUnit
) == NULL
) {
3872 SC_log(LOG_INFO
, "No IOInterfaceUnit");
3876 ioMACAddress
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOMACAddress
));
3877 if (isA_CFData(ioMACAddress
) == NULL
) {
3878 SC_log(LOG_INFO
, "No IOMACAddress");
3881 ioPathMatch
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOPathMatch
));
3882 if (isA_CFString(ioPathMatch
) == NULL
) {
3883 SC_log(LOG_INFO
, "No IOPathMatch");
3886 // Check if Path contains the BSD Name in the end
3888 SCNetworkInterfaceInfo
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceInfo
));
3889 if (isA_CFDictionary(SCNetworkInterfaceInfo
) == NULL
) {
3890 SC_log(LOG_INFO
, "No SCNetworkInterfaceInfo");
3893 userDefinedName
= CFDictionaryGetValue(SCNetworkInterfaceInfo
, kSCPropUserDefinedName
);
3894 #if !TARGET_IPHONE_SIMULATOR
3895 usbProductName
= CFDictionaryGetValue(SCNetworkInterfaceInfo
, CFSTR(kUSBProductString
));
3896 idProduct
= CFDictionaryGetValue(SCNetworkInterfaceInfo
, CFSTR(kUSBProductID
));
3897 idVendor
= CFDictionaryGetValue(SCNetworkInterfaceInfo
, CFSTR(kUSBVendorID
));
3898 #endif // !TARGET_IPHONE_SIMULATOR
3900 type
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceType
));
3901 if (isA_CFString(type
) == NULL
) {
3902 SC_log(LOG_INFO
, "No SCNetworkInterfaceType");
3906 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
);
3907 interfacePrivate
->active
= CFBooleanGetValue(active
);
3908 interfacePrivate
->entity_device
= CFRetain(bsdName
);
3909 interfacePrivate
->builtin
= CFBooleanGetValue(ioBuiltin
);
3910 interfacePrivate
->prefix
= CFRetain(ioInterfaceNamePrefix
);
3911 interfacePrivate
->type
= CFRetain(ioInterfaceType
);
3912 interfacePrivate
->unit
= CFRetain(ioInterfaceUnit
);
3913 interfacePrivate
->address
= CFRetain(ioMACAddress
);
3914 interfacePrivate
->path
= CFRetain(ioPathMatch
);
3915 interfacePrivate
->name
= ((userDefinedName
!= NULL
) ? CFRetain(userDefinedName
) : NULL
);
3916 interfacePrivate
->localized_name
= ((userDefinedName
!= NULL
) ? CFRetain(userDefinedName
) : NULL
);
3917 interfacePrivate
->usb
.name
= ((usbProductName
!= NULL
) ? CFRetain(usbProductName
) : NULL
);
3918 interfacePrivate
->usb
.pid
= ((idProduct
!= NULL
) ? CFRetain(idProduct
) : NULL
);
3919 interfacePrivate
->usb
.vid
= ((idVendor
!= NULL
) ? CFRetain(idVendor
) : NULL
);
3921 // Handling interface types to be seen in NetworkInterfaces.plist
3922 CFIndex interfaceIndex
;
3924 interfaceIndex
= findConfiguration(type
);
3925 if (interfaceIndex
!= kCFNotFound
) {
3926 interfacePrivate
->interface_type
= *configurations
[interfaceIndex
].interface_type
;
3928 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
3931 // Extracting entity type from value of interface type
3932 if (ioInterfaceTypeNum
== kInterfaceTypeEthernetValue
) {
3933 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
; // kSCNetworkInterfaceTypeEthernet;
3934 } else if (ioInterfaceTypeNum
== kInterfaceTypeFirewireValue
) {
3935 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeFireWire
;
3938 if (ioInterfaceNamePrefix
!= NULL
) {
3939 CFRelease(ioInterfaceNamePrefix
);
3942 return (SCNetworkInterfaceRef
)interfacePrivate
;
3946 SCNetworkInterfaceRef
3947 _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef allocator
,
3948 CFDictionaryRef interface_entity
,
3949 SCNetworkServiceRef service
)
3951 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
3952 CFStringRef ifDevice
;
3953 CFStringRef ifName
= NULL
;
3954 CFStringRef ifSubType
;
3956 CFStringRef ifUnique
;
3957 CFArrayRef matching_interfaces
= NULL
;
3958 SCPreferencesRef servicePref
= NULL
;
3959 Boolean useSystemInterfaces
= TRUE
;
3961 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
3962 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
3964 if (service
!= NULL
) {
3965 servicePref
= ((SCNetworkServicePrivateRef
)service
)->prefs
;
3966 useSystemInterfaces
= ((__SCPreferencesUsingDefaultPrefs(servicePref
)) &&
3967 (__SCPreferencesGetLimitSCNetworkConfiguration(servicePref
) == FALSE
));
3970 ifType
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceType
);
3971 if (ifType
== NULL
) {
3973 * The interface "Type" was not specified. We'll make an
3974 * assumption that this is an "Ethernet" interface. If a
3975 * real interface exists with the provided interface name
3976 * then the actual type will be set accordingly. If not, we'll
3977 * end up crafting an "Ethernet" SCNetworkInterface that
3978 * will keep the rest of the configuration APIs happy.
3980 ifType
= kSCValNetInterfaceTypeEthernet
;
3983 if (!isA_CFString(ifType
)) {
3987 ifSubType
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceSubType
);
3988 if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) ||
3989 CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
3990 if (!isA_CFString(ifSubType
)) {
3995 ifDevice
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceDeviceName
);
3996 ifUnique
= CFDictionaryGetValue(interface_entity
, CFSTR("DeviceUniqueIdentifier"));
3998 if (CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
) ||
3999 CFEqual(ifType
, kSCValNetInterfaceTypeFireWire
) ||
4000 (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) && CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPoE
))) {
4001 char bsdName
[IFNAMSIZ
];
4002 CFMutableDictionaryRef matching
;
4004 if (!isA_CFString(ifDevice
)) {
4008 if (CFEqual(ifDevice
, CFSTR("lo0"))) { // for _SCNetworkInterfaceCreateWithBSDName
4009 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
4012 if (useSystemInterfaces
) {
4013 if (_SC_cfstring_to_cstring(ifDevice
, bsdName
, sizeof(bsdName
), kCFStringEncodingASCII
) == NULL
) {
4017 matching
= IOBSDNameMatching(masterPort
, 0, bsdName
);
4018 if (matching
== NULL
) {
4021 matching_interfaces
= findMatchingInterfaces(matching
, processNetworkInterface
, kSCNetworkInterfaceHiddenInterfaceKey
);
4022 CFRelease(matching
);
4024 } else if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
4025 if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPSerial
)) {
4026 CFDictionaryRef matching
;
4027 CFStringRef match_keys
[2];
4028 CFStringRef match_vals
[2];
4030 if (!isA_CFString(ifDevice
)) {
4034 if (useSystemInterfaces
) {
4035 match_keys
[0] = CFSTR(kIOProviderClassKey
);
4036 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
4038 match_keys
[1] = CFSTR(kIOTTYBaseNameKey
);
4039 match_vals
[1] = ifDevice
;
4041 matching
= CFDictionaryCreate(NULL
,
4042 (const void **)match_keys
,
4043 (const void **)match_vals
,
4044 sizeof(match_keys
)/sizeof(match_keys
[0]),
4045 &kCFTypeDictionaryKeyCallBacks
,
4046 &kCFTypeDictionaryValueCallBacks
);
4047 matching_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
, kSCNetworkInterfaceHiddenPortKey
);
4048 CFRelease(matching
);
4050 if (ifUnique
== NULL
) {
4052 Boolean useDeviceName
= TRUE
;
4054 n
= (matching_interfaces
!= NULL
) ? CFArrayGetCount(matching_interfaces
) : 0;
4058 for (i
= 0; i
< n
; i
++) {
4059 SCNetworkInterfacePrivateRef scanPrivate
;
4061 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
4062 if (scanPrivate
->entity_device_unique
!= NULL
) {
4063 useDeviceName
= FALSE
;
4069 if (useDeviceName
&& useSystemInterfaces
) {
4070 if (matching_interfaces
!= NULL
) {
4071 CFRelease(matching_interfaces
);
4074 match_keys
[1] = CFSTR(kIOTTYDeviceKey
);
4075 matching
= CFDictionaryCreate(NULL
,
4076 (const void **)match_keys
,
4077 (const void **)match_vals
,
4078 sizeof(match_keys
)/sizeof(match_keys
[0]),
4079 &kCFTypeDictionaryKeyCallBacks
,
4080 &kCFTypeDictionaryValueCallBacks
);
4081 matching_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
, kSCNetworkInterfaceHiddenPortKey
);
4082 CFRelease(matching
);
4085 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypeL2TP
)) {
4086 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4087 kSCNetworkInterfaceTypeL2TP
);
4088 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPTP
)) {
4089 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4090 kSCNetworkInterfaceTypePPTP
);
4092 // XXX do we allow non-Apple variants of PPP??? XXX
4093 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4096 } else if (CFEqual(ifType
, kSCValNetInterfaceType6to4
)) {
4097 if (!isA_CFString(ifDevice
)) {
4101 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4102 kSCNetworkInterfaceType6to4
);
4103 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeIPSec
)) {
4104 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4105 kSCNetworkInterfaceTypeIPSec
);
4106 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeLoopback
)) {
4107 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
4108 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
4109 if (CFStringFind(ifSubType
, CFSTR("."), 0).location
!= kCFNotFound
) {
4110 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4113 } else if ((CFStringFind(ifType
, CFSTR("."), 0).location
!= kCFNotFound
) && (ifDevice
== NULL
)) {
4114 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4118 if (matching_interfaces
!= NULL
) {
4120 SCPreferencesRef prefs
;
4121 Boolean temp_preferences
= FALSE
;
4123 n
= CFArrayGetCount(matching_interfaces
);
4126 interfacePrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, 0);
4127 if (_SC_CFEqual(ifUnique
, interfacePrivate
->entity_device_unique
)) {
4128 // if the unique ID's match
4129 CFRetain(interfacePrivate
);
4133 interfacePrivate
= NULL
;
4136 if (!CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
)) {
4140 if (CFDictionaryGetValueIfPresent(interface_entity
,
4141 kSCPropUserDefinedName
,
4142 (const void **)&ifName
) &&
4143 CFEqual(ifName
, CFSTR(BT_PAN_NAME
))) {
4147 prefs
= (service
!= NULL
) ? ((SCNetworkServicePrivateRef
)service
)->prefs
: NULL
;
4148 if (prefs
== NULL
) {
4149 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), NULL
);
4150 if (prefs
!= NULL
) {
4151 temp_preferences
= TRUE
;
4154 if (prefs
== NULL
) {
4157 #if !TARGET_OS_IPHONE
4158 if (!CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_BOND_INTERFACES_"))) {
4159 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findBondInterface(prefs
, ifDevice
);
4161 #endif // !TARGET_OS_IPHONE
4162 if ((interfacePrivate
== NULL
)
4163 && !CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_BRIDGE_INTERFACES_"))) {
4164 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findBridgeInterface(prefs
, ifDevice
);
4167 if ((interfacePrivate
== NULL
)
4168 && !CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_VLAN_INTERFACES_"))) {
4169 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findVLANInterface(prefs
, ifDevice
);
4171 if (temp_preferences
) CFRelease(prefs
);
4174 if (ifUnique
!= NULL
) {
4177 // we are looking for an interface with a unique ID
4178 // so let's try to focus our choices
4179 for (i
= 0; i
< n
; i
++) {
4180 SCNetworkInterfacePrivateRef scanPrivate
;
4182 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
4183 if (_SC_CFEqual(ifUnique
, scanPrivate
->entity_device_unique
)) {
4184 if (interfacePrivate
!= NULL
) {
4185 // if we've matched more than one interface
4186 interfacePrivate
= NULL
;
4189 interfacePrivate
= scanPrivate
;
4192 } else if (CFDictionaryGetValueIfPresent(interface_entity
,
4193 kSCPropUserDefinedName
,
4194 (const void **)&ifName
)) {
4197 // we don't have a unique ID but do have an interface
4198 // name. If the matching interfaces do have IDs than
4199 // we can try to focus our choices using the name
4200 for (i
= 0; i
< n
; i
++) {
4201 SCNetworkInterfacePrivateRef scanPrivate
;
4203 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
4204 if (scanPrivate
->entity_device_unique
!= NULL
) {
4205 SCNetworkInterfaceRef scan
= (SCNetworkInterfaceRef
)scanPrivate
;
4206 CFStringRef scanName
;
4208 scanName
= __SCNetworkInterfaceGetNonLocalizedDisplayName(scan
);
4209 if ((scanName
!= NULL
) && !_SC_CFEqual(ifName
, scanName
)) {
4210 continue; // if not the same display name
4214 if (interfacePrivate
!= NULL
) {
4215 // if we've matched more than one interface
4216 interfacePrivate
= NULL
;
4219 interfacePrivate
= scanPrivate
;
4222 if (interfacePrivate
== NULL
) {
4223 SC_log(LOG_NOTICE
, "more than one interface matches %@", ifDevice
);
4224 interfacePrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, 0);
4226 CFRetain(interfacePrivate
);
4229 CFRelease(matching_interfaces
);
4234 if ((interfacePrivate
== NULL
) || (useSystemInterfaces
== FALSE
)) {
4236 * if device not present on this system
4238 if (useSystemInterfaces
== FALSE
) {
4239 if (interfacePrivate
!= NULL
) {
4240 CFRelease(interfacePrivate
);
4244 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
);
4245 interfacePrivate
->entity_type
= (ifType
!= NULL
) ? ifType
: NULL
;
4246 interfacePrivate
->entity_subtype
= (ifSubType
!= NULL
) ? ifSubType
: NULL
;
4247 interfacePrivate
->entity_device
= (ifDevice
!= NULL
) ? CFStringCreateCopy(NULL
, ifDevice
) : NULL
;
4248 interfacePrivate
->entity_device_unique
= (ifUnique
!= NULL
) ? CFStringCreateCopy(NULL
, ifUnique
) : NULL
;
4250 // Using UserDefinedName to check the validity of preferences file
4251 // when useSystemInterfaces is FALSE
4252 if (useSystemInterfaces
== FALSE
) {
4253 CFStringRef userDefinedName
= CFDictionaryGetValue(interface_entity
, kSCPropUserDefinedName
);
4254 if (isA_CFString(userDefinedName
) != NULL
) {
4255 CFRetain(userDefinedName
);
4256 if (interfacePrivate
->name
!= NULL
) {
4257 CFRelease(interfacePrivate
->name
);
4259 interfacePrivate
->name
= userDefinedName
;
4261 CFRetain(userDefinedName
);
4262 if (interfacePrivate
->localized_name
!= NULL
) {
4263 CFRelease(interfacePrivate
->localized_name
);
4265 interfacePrivate
->localized_name
= userDefinedName
;
4269 if (CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
)) {
4270 CFStringRef entity_hardware
;
4271 SCNetworkInterfaceRef virtualInterface
;
4273 if ((useSystemInterfaces
== FALSE
) &&
4274 (((virtualInterface
= findBridgeInterface(servicePref
, ifDevice
)) != NULL
) ||
4275 #if !TARGET_OS_IPHONE
4276 ((virtualInterface
= findBondInterface(servicePref
, ifDevice
)) != NULL
) ||
4278 ((virtualInterface
= findVLANInterface(servicePref
, ifDevice
)) != NULL
))) {
4279 CFRelease(interfacePrivate
);
4280 interfacePrivate
= (SCNetworkInterfacePrivateRef
)virtualInterface
;
4282 entity_hardware
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceHardware
);
4283 if (isA_CFString((entity_hardware
)) &&
4284 CFEqual(entity_hardware
, kSCEntNetAirPort
)) {
4285 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
4286 interfacePrivate
->localized_key
= CFSTR("airport");
4287 interfacePrivate
->sort_order
= kSortAirPort
;
4291 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
4293 name
= CFDictionaryGetValue(interface_entity
, kSCPropUserDefinedName
);
4294 if (__SCNetworkInterfaceMatchesName(name
, CFSTR("iPhone"))) {
4295 interfacePrivate
->localized_key
= CFSTR("iPhone");
4296 interfacePrivate
->sort_order
= kSortTethered
;
4297 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("iPad"))) {
4298 interfacePrivate
->localized_key
= CFSTR("iPad");
4299 interfacePrivate
->sort_order
= kSortTethered
;
4300 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("thunderbolt"))) {
4301 interfacePrivate
->localized_key
= CFSTR("thunderbolt");
4302 interfacePrivate
->sort_order
= kSortThunderbolt
;
4303 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-gn"))) {
4304 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-gn");
4305 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
4306 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-nap"))) {
4307 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-nap");
4308 interfacePrivate
->sort_order
= kSortBluetoothPAN_NAP
;
4309 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-u"))) {
4310 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-u");
4311 interfacePrivate
->sort_order
= kSortBluetoothPAN_U
;
4313 interfacePrivate
->sort_order
= kSortEthernet
;
4317 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeFireWire
)) {
4318 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeFireWire
;
4319 interfacePrivate
->sort_order
= kSortFireWire
;
4320 } else if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
4321 if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPoE
)) {
4322 CFStringRef entity_hardware
;
4324 entity_hardware
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceHardware
);
4325 if (isA_CFString((entity_hardware
)) &&
4326 CFEqual(entity_hardware
, kSCEntNetAirPort
)) {
4327 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
4328 interfacePrivate
->sort_order
= kSortAirPort
;
4330 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
4331 interfacePrivate
->sort_order
= kSortEthernet
;
4333 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPSerial
)) {
4334 if (CFStringHasPrefix(ifDevice
, CFSTR("Bluetooth"))) {
4335 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBluetooth
;
4336 interfacePrivate
->sort_order
= kSortBluetooth
;
4337 } else if (CFStringHasPrefix(ifDevice
, CFSTR("irda"))) {
4338 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIrDA
;
4339 interfacePrivate
->sort_order
= kSortIrDA
;
4340 } else if (CFStringHasPrefix(ifDevice
, CFSTR("wwan"))) {
4341 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeWWAN
;
4342 interfacePrivate
->sort_order
= kSortWWAN
;
4344 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeModem
;
4345 interfacePrivate
->sort_order
= kSortModem
;
4348 SCNetworkInterfaceRef child
;
4350 CFRelease(interfacePrivate
);
4351 child
= SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
, ifSubType
);
4352 interfacePrivate
= (SCNetworkInterfacePrivateRef
)child
;
4353 if (interfacePrivate
== NULL
) {
4357 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
4358 SCNetworkInterfaceRef child
;
4359 CFRelease(interfacePrivate
);
4360 child
= SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
, ifSubType
);
4361 interfacePrivate
= (SCNetworkInterfacePrivateRef
)child
;
4362 if (interfacePrivate
== NULL
) {
4365 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeIPSec
)) {
4366 CFRelease(interfacePrivate
);
4367 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4368 kSCNetworkInterfaceTypeIPSec
);
4369 } else if (CFEqual(ifType
, kSCValNetInterfaceType6to4
)) {
4370 CFRelease(interfacePrivate
);
4371 if (!isA_CFString(ifDevice
)) {
4374 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4375 kSCNetworkInterfaceType6to4
);
4376 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeLoopback
)) {
4377 CFRelease(interfacePrivate
);
4378 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
4379 } else if (CFStringFind(ifType
, CFSTR("."), 0).location
!= kCFNotFound
) {
4380 // if vendor interface
4381 if (vendor_interface_types
== NULL
) {
4382 vendor_interface_types
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
4384 CFSetAddValue(vendor_interface_types
, ifType
);
4386 interfacePrivate
->interface_type
= CFSetGetValue(vendor_interface_types
, ifType
);
4388 // if unknown interface
4389 CFRelease(interfacePrivate
);
4390 interfacePrivate
= NULL
;
4394 if (CFDictionaryContainsKey(interface_entity
, kSCNetworkInterfaceHiddenConfigurationKey
)) {
4395 interfacePrivate
->hidden
= TRUE
;
4399 if (service
!= NULL
) {
4400 __SCNetworkInterfaceSetService((SCNetworkInterfaceRef
)interfacePrivate
,
4403 #if !TARGET_OS_IPHONE
4404 // set prefs & serviceID to Bond member interfaces
4405 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBond
)) {
4410 members
= SCBondInterfaceGetMemberInterfaces((SCNetworkInterfaceRef
)interfacePrivate
);
4411 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
4412 for (i
= 0; i
< n
; i
++) {
4413 SCNetworkInterfaceRef member
;
4415 member
= CFArrayGetValueAtIndex(members
, i
);
4416 __SCNetworkInterfaceSetService(member
, service
);
4419 #endif // !TARGET_OS_IPHONE
4421 // set prefs & serviceID to Bridge member interfaces
4422 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBridge
)) {
4427 members
= SCBridgeInterfaceGetMemberInterfaces((SCNetworkInterfaceRef
)interfacePrivate
);
4428 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
4429 for (i
= 0; i
< n
; i
++) {
4430 SCNetworkInterfaceRef member
;
4432 member
= CFArrayGetValueAtIndex(members
, i
);
4433 __SCNetworkInterfaceSetService(member
, service
);
4436 // set prefs & serviceID to VLAN pyhsical interface
4437 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeVLAN
)) {
4438 SCNetworkInterfaceRef vlan_physical
;
4440 vlan_physical
= SCVLANInterfaceGetPhysicalInterface((SCNetworkInterfaceRef
)interfacePrivate
);
4441 if (vlan_physical
!= NULL
) {
4442 __SCNetworkInterfaceSetService(vlan_physical
, service
);
4447 if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
4448 SCNetworkInterfaceRef parent
;
4451 parent
= SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef
)interfacePrivate
,
4452 kSCNetworkInterfaceTypePPP
);
4453 CFRelease(interfacePrivate
);
4454 interfacePrivate
= (SCNetworkInterfacePrivateRef
)parent
;
4455 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
4456 SCNetworkInterfaceRef parent
;
4459 parent
= SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef
)interfacePrivate
,
4460 kSCNetworkInterfaceTypeVPN
);
4461 CFRelease(interfacePrivate
);
4462 interfacePrivate
= (SCNetworkInterfacePrivateRef
)parent
;
4465 return (SCNetworkInterfaceRef
)interfacePrivate
;
4470 #pragma mark SCNetworkInterface APIs
4475 __SCNetworkInterfaceCopyAll_IONetworkInterface(void)
4477 CFDictionaryRef matching
;
4478 CFArrayRef new_interfaces
;
4480 // get Ethernet, Firewire, Thunderbolt, and AirPort interfaces
4482 matching
= IOServiceMatching(kIONetworkInterfaceClass
);
4483 new_interfaces
= findMatchingInterfaces(matching
, processNetworkInterface
, kSCNetworkInterfaceHiddenInterfaceKey
);
4484 CFRelease(matching
);
4486 return new_interfaces
;
4492 __SCNetworkInterfaceCopyAll_Modem()
4494 CFDictionaryRef matching
;
4495 CFStringRef match_keys
[2];
4496 CFStringRef match_vals
[2];
4497 CFArrayRef new_interfaces
;
4499 match_keys
[0] = CFSTR(kIOProviderClassKey
);
4500 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
4502 match_keys
[1] = CFSTR(kIOSerialBSDTypeKey
);
4503 match_vals
[1] = CFSTR(kIOSerialBSDModemType
);
4505 matching
= CFDictionaryCreate(NULL
,
4506 (const void **)match_keys
,
4507 (const void **)match_vals
,
4508 sizeof(match_keys
)/sizeof(match_keys
[0]),
4509 &kCFTypeDictionaryKeyCallBacks
,
4510 &kCFTypeDictionaryValueCallBacks
);
4511 new_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
, kSCNetworkInterfaceHiddenPortKey
);
4512 CFRelease(matching
);
4514 return new_interfaces
;
4520 __SCNetworkInterfaceCopyAll_RS232()
4522 CFDictionaryRef matching
;
4523 CFStringRef match_keys
[2];
4524 CFStringRef match_vals
[2];
4525 CFArrayRef new_interfaces
;
4527 match_keys
[0] = CFSTR(kIOProviderClassKey
);
4528 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
4530 match_keys
[1] = CFSTR(kIOSerialBSDTypeKey
);
4531 match_vals
[1] = CFSTR(kIOSerialBSDRS232Type
);
4533 matching
= CFDictionaryCreate(NULL
,
4534 (const void **)match_keys
,
4535 (const void **)match_vals
,
4536 sizeof(match_keys
)/sizeof(match_keys
[0]),
4537 &kCFTypeDictionaryKeyCallBacks
,
4538 &kCFTypeDictionaryValueCallBacks
);
4539 new_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
, kSCNetworkInterfaceHiddenPortKey
);
4540 CFRelease(matching
);
4542 return new_interfaces
;
4546 #if !TARGET_OS_IPHONE
4548 addBTPANInterface(SCPreferencesRef prefs
, CFMutableArrayRef all_interfaces
)
4551 SCNetworkInterfaceRef interface
;
4554 n
= CFArrayGetCount(all_interfaces
);
4555 for (i
= 0; i
< n
; i
++) {
4556 SCNetworkInterfaceRef interface
;
4558 interface
= CFArrayGetValueAtIndex(all_interfaces
, i
);
4559 if (_SCNetworkInterfaceIsBluetoothPAN(interface
)) {
4560 // if we already have a BT-PAN interface
4565 interface
= _SCNetworkInterfaceCopyBTPANInterface();
4566 if (interface
!= NULL
) {
4567 // include BT-PAN interface
4568 CFArrayAppendValue(all_interfaces
, interface
);
4569 CFRelease(interface
);
4574 #endif // !TARGET_OS_IPHONE
4578 add_interfaces(CFMutableArrayRef all_interfaces
, CFArrayRef new_interfaces
)
4583 n
= CFArrayGetCount(new_interfaces
);
4584 for (i
= 0; i
< n
; i
++) {
4585 CFStringRef bsdName
;
4586 SCNetworkInterfaceRef interface
;
4588 interface
= CFArrayGetValueAtIndex(new_interfaces
, i
);
4589 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
4590 if (bsdName
!= NULL
) {
4591 CFArrayAppendValue(all_interfaces
, interface
);
4600 __waitForInterfaces()
4605 SCDynamicStoreRef store
;
4607 store
= SCDynamicStoreCreate(NULL
, CFSTR("SCNetworkInterfaceCopyAll"), NULL
, NULL
);
4608 if (store
== NULL
) {
4612 key
= SCDynamicStoreKeyCreate(NULL
, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin
);
4613 keys
= CFArrayCreate(NULL
, (const void **)&key
, 1, &kCFTypeArrayCallBacks
);
4614 ok
= SCDynamicStoreSetNotificationKeys(store
, keys
, NULL
);
4617 SC_log(LOG_NOTICE
, "SCDynamicStoreSetNotificationKeys() failed: %s", SCErrorString(SCError()));
4622 CFArrayRef changedKeys
;
4623 CFDictionaryRef dict
;
4624 Boolean quiet
= FALSE
;
4627 dict
= SCDynamicStoreCopyValue(store
, key
);
4629 if (isA_CFDictionary(dict
) &&
4630 (CFDictionaryContainsKey(dict
, CFSTR("*QUIET*")) ||
4631 CFDictionaryContainsKey(dict
, CFSTR("*TIMEOUT*")))) {
4640 ok
= SCDynamicStoreNotifyWait(store
);
4642 SC_log(LOG_NOTICE
, "SCDynamicStoreNotifyWait() failed: %s", SCErrorString(SCError()));
4646 changedKeys
= SCDynamicStoreCopyNotifiedKeys(store
);
4647 if (changedKeys
!= NULL
) {
4648 CFRelease(changedKeys
);
4660 CFArrayRef
/* of SCNetworkInterfaceRef's */
4661 _SCNetworkInterfaceCopyAllWithPreferences(SCPreferencesRef prefs
)
4663 CFMutableArrayRef all_interfaces
;
4664 CFArrayRef new_interfaces
;
4665 Boolean temp_preferences
= FALSE
;
4667 /* initialize runtime */
4668 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4670 /* wait for IOKit to quiesce */
4671 pthread_once(&iokit_quiet
, __waitForInterfaces
);
4673 all_interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4675 // get Ethernet, Firewire, Thunderbolt, and AirPort interfaces
4676 new_interfaces
= __SCNetworkInterfaceCopyAll_IONetworkInterface();
4677 if (new_interfaces
!= NULL
) {
4678 add_interfaces(all_interfaces
, new_interfaces
);
4679 CFRelease(new_interfaces
);
4682 // get Modem interfaces
4683 new_interfaces
= __SCNetworkInterfaceCopyAll_Modem();
4684 if (new_interfaces
!= NULL
) {
4685 add_interfaces(all_interfaces
, new_interfaces
);
4686 CFRelease(new_interfaces
);
4689 // get serial (RS232) interfaces
4690 new_interfaces
= __SCNetworkInterfaceCopyAll_RS232();
4691 if (new_interfaces
!= NULL
) {
4692 add_interfaces(all_interfaces
, new_interfaces
);
4693 CFRelease(new_interfaces
);
4696 // get virtual network interfaces (Bond, Bridge, VLAN)
4697 if (prefs
== NULL
) {
4698 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterfaceCopyAll"), NULL
);
4699 if (prefs
!= NULL
) {
4700 temp_preferences
= TRUE
;
4703 if (prefs
!= NULL
) {
4704 #if !TARGET_OS_IPHONE
4705 new_interfaces
= SCBondInterfaceCopyAll(prefs
);
4706 if (new_interfaces
!= NULL
) {
4707 add_interfaces(all_interfaces
, new_interfaces
);
4708 CFRelease(new_interfaces
);
4710 #endif // !TARGET_OS_IPHONE
4712 new_interfaces
= SCBridgeInterfaceCopyAll(prefs
);
4713 if (new_interfaces
!= NULL
) {
4714 add_interfaces(all_interfaces
, new_interfaces
);
4715 CFRelease(new_interfaces
);
4718 new_interfaces
= SCVLANInterfaceCopyAll(prefs
);
4719 if (new_interfaces
!= NULL
) {
4720 add_interfaces(all_interfaces
, new_interfaces
);
4721 CFRelease(new_interfaces
);
4724 #if !TARGET_OS_IPHONE
4725 // add BT-PAN interface
4726 addBTPANInterface(prefs
, all_interfaces
);
4727 #endif // !TARGET_OS_IPHONE
4729 if (temp_preferences
) CFRelease(prefs
);
4732 // all interfaces have been identified, order and return
4733 sort_interfaces(all_interfaces
);
4735 return all_interfaces
;
4739 CFArrayRef
/* of SCNetworkInterfaceRef's */
4740 SCNetworkInterfaceCopyAll()
4742 CFArrayRef all_interfaces
;
4744 all_interfaces
= _SCNetworkInterfaceCopyAllWithPreferences(NULL
);
4745 return all_interfaces
;
4749 CFArrayRef
/* of kSCNetworkInterfaceTypeXXX CFStringRef's */
4750 SCNetworkInterfaceGetSupportedInterfaceTypes(SCNetworkInterfaceRef interface
)
4753 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4755 if (!isA_SCNetworkInterface(interface
)) {
4756 _SCErrorSet(kSCStatusInvalidArgument
);
4760 if (interfacePrivate
->supported_interface_types
!= NULL
) {
4764 i
= findConfiguration(interfacePrivate
->interface_type
);
4765 if (i
!= kCFNotFound
) {
4766 if (configurations
[i
].supported_interfaces
!= doNone
) {
4767 interfacePrivate
->supported_interface_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4768 if (configurations
[i
].supported_interfaces
& do6to4
) {
4769 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceType6to4
);
4771 if (configurations
[i
].supported_interfaces
& doL2TP
) {
4772 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeL2TP
);
4774 if (configurations
[i
].supported_interfaces
& doPPP
) {
4775 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypePPP
);
4777 if (configurations
[i
].supported_interfaces
& doPPTP
) {
4778 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypePPTP
);
4780 if (configurations
[i
].supported_interfaces
& doIPSec
) {
4781 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeIPSec
);
4785 SCNetworkInterfaceRef child
;
4787 child
= SCNetworkInterfaceGetInterface(interface
);
4788 if ((child
!= NULL
) && CFEqual(child
, kSCNetworkInterfaceIPv4
)) {
4789 interfacePrivate
->supported_interface_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4790 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeVPN
);
4796 return interfacePrivate
->supported_interface_types
;
4800 CFArrayRef
/* of kSCNetworkProtocolTypeXXX CFStringRef's */
4801 SCNetworkInterfaceGetSupportedProtocolTypes(SCNetworkInterfaceRef interface
)
4804 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4806 if (!isA_SCNetworkInterface(interface
)) {
4807 _SCErrorSet(kSCStatusInvalidArgument
);
4811 if (interfacePrivate
->supported_protocol_types
!= NULL
) {
4815 i
= findConfiguration(interfacePrivate
->interface_type
);
4816 if (i
!= kCFNotFound
) {
4817 if (configurations
[i
].supported_protocols
!= doNone
) {
4818 interfacePrivate
->supported_protocol_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4819 if (configurations
[i
].supported_protocols
& doDNS
) {
4820 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeDNS
);
4822 if (configurations
[i
].supported_protocols
& doIPv4
) {
4823 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeIPv4
);
4825 if (configurations
[i
].supported_protocols
& doIPv6
) {
4826 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeIPv6
);
4828 if (configurations
[i
].supported_protocols
& doProxies
) {
4829 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeProxies
);
4831 #if !TARGET_OS_IPHONE
4832 if (configurations
[i
].supported_protocols
& doSMB
) {
4833 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeSMB
);
4835 #endif // !TARGET_OS_IPHONE
4841 return interfacePrivate
->supported_protocol_types
;
4845 SCNetworkInterfaceRef
4846 SCNetworkInterfaceCreateWithInterface(SCNetworkInterfaceRef child
, CFStringRef interfaceType
)
4848 SCNetworkInterfacePrivateRef childPrivate
= (SCNetworkInterfacePrivateRef
)child
;
4850 SCNetworkInterfacePrivateRef parentPrivate
;
4852 if (!isA_SCNetworkInterface(child
)) {
4853 _SCErrorSet(kSCStatusInvalidArgument
);
4857 if (!isA_CFString(interfaceType
)) {
4858 _SCErrorSet(kSCStatusInvalidArgument
);
4862 if (CFEqual(child
, kSCNetworkInterfaceLoopback
)) {
4863 // can't layer on top of loopback
4864 _SCErrorSet(kSCStatusInvalidArgument
);
4868 childIndex
= findConfiguration(childPrivate
->interface_type
);
4870 parentPrivate
= __SCNetworkInterfaceCreatePrivate(NULL
,
4872 childPrivate
->prefs
,
4873 childPrivate
->serviceID
);
4874 if (parentPrivate
== NULL
) {
4875 _SCErrorSet(kSCStatusFailed
);
4879 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
4880 parentPrivate
->interface_type
= kSCNetworkInterfaceTypePPP
;
4881 parentPrivate
->entity_type
= kSCValNetInterfaceTypePPP
;
4884 if (childIndex
!= kCFNotFound
) {
4885 if (configurations
[childIndex
].ppp_subtype
!= NULL
) {
4886 parentPrivate
->entity_subtype
= *configurations
[childIndex
].ppp_subtype
;
4888 // sorry, the child interface does not support PPP
4892 // if the child's interface type not known, use the child entities "Type"
4893 parentPrivate
->entity_subtype
= childPrivate
->entity_type
;
4896 if (childPrivate
->entity_device
!= NULL
) {
4897 parentPrivate
->entity_device
= CFStringCreateCopy(NULL
, childPrivate
->entity_device
);
4900 if (childPrivate
->entity_device_unique
!= NULL
) {
4901 parentPrivate
->entity_device_unique
= CFStringCreateCopy(NULL
, childPrivate
->entity_device_unique
);
4903 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
4904 if ((childIndex
== kCFNotFound
) ||
4905 ((configurations
[childIndex
].supported_interfaces
& doL2TP
) != doL2TP
)) {
4906 // if the child interface does not support L2TP
4909 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeL2TP
;
4910 parentPrivate
->localized_key
= CFSTR("l2tp");
4911 parentPrivate
->entity_type
= kSCEntNetL2TP
; // interface config goes into "L2TP"
4912 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPTP
)) {
4913 if ((childIndex
== kCFNotFound
) ||
4914 ((configurations
[childIndex
].supported_interfaces
& doPPTP
) != doPPTP
)) {
4915 // if the child interface does not support PPTP
4918 parentPrivate
->interface_type
= kSCNetworkInterfaceTypePPTP
;
4919 parentPrivate
->localized_key
= CFSTR("pptp");
4920 parentPrivate
->entity_type
= kSCEntNetPPTP
; // interface config goes into "PPTP"
4921 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceType6to4
)) {
4922 if ((childIndex
== kCFNotFound
) ||
4923 ((configurations
[childIndex
].supported_interfaces
& do6to4
) != do6to4
)) {
4924 // if the child interface does not support 6to4
4928 parentPrivate
->interface_type
= kSCNetworkInterfaceType6to4
;
4929 parentPrivate
->localized_key
= CFSTR("6to4");
4930 parentPrivate
->entity_type
= kSCValNetInterfaceType6to4
;
4931 parentPrivate
->entity_device
= CFRetain(CFSTR("stf0"));
4932 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
4933 if ((childIndex
== kCFNotFound
) ||
4934 ((configurations
[childIndex
].supported_interfaces
& doIPSec
) != doIPSec
)) {
4935 // if the child interface does not support IPSec
4938 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeIPSec
;
4939 parentPrivate
->localized_key
= CFSTR("ipsec");
4940 parentPrivate
->entity_type
= kSCValNetInterfaceTypeIPSec
;
4941 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) {
4942 if (childIndex
!= kCFNotFound
) {
4943 // if not a "vendor" child interface
4947 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeVPN
;
4948 parentPrivate
->localized_key
= CFSTR("vpn");
4949 parentPrivate
->localized_arg1
= CFRetain(childPrivate
->entity_type
);
4950 parentPrivate
->entity_type
= kSCValNetInterfaceTypeVPN
;
4951 parentPrivate
->entity_subtype
= childPrivate
->entity_type
;
4952 if (childPrivate
->entity_device
!= NULL
) {
4953 parentPrivate
->entity_device
= CFStringCreateCopy(NULL
, childPrivate
->entity_device
);
4955 if (parentPrivate
->entity_subtype
!= NULL
) {
4956 CFArrayRef components
;
4958 CFStringRef vpnType
;
4961 // the "default" interface name is derived from the VPN type
4964 // com.apple.Apple-VPN.vpnplugin --> "Apple VPN"
4967 vpnType
= parentPrivate
->entity_subtype
;
4968 components
= CFStringCreateArrayBySeparatingStrings(NULL
, vpnType
, CFSTR("."));
4969 n
= CFArrayGetCount(components
);
4971 CFEqual(CFArrayGetValueAtIndex(components
, n
- 1), CFSTR("vpnplugin"))) {
4972 CFMutableStringRef str
;
4974 str
= CFStringCreateMutableCopy(NULL
,
4976 CFArrayGetValueAtIndex(components
, n
- 2));
4977 (void) CFStringFindAndReplace(str
,
4980 CFRangeMake(0, CFStringGetLength(str
)),
4982 parentPrivate
->localized_name
= str
;
4984 CFRelease(components
);
4986 } else if (CFStringFind(interfaceType
, CFSTR("."), 0).location
!= kCFNotFound
) {
4987 // if custom interface type
4988 if (vendor_interface_types
== NULL
) {
4989 vendor_interface_types
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
4991 CFSetAddValue(vendor_interface_types
, interfaceType
);
4993 parentPrivate
->interface_type
= CFSetGetValue(vendor_interface_types
, interfaceType
);
4994 parentPrivate
->entity_type
= parentPrivate
->interface_type
; // interface config goes into a
4995 // a dictionary with the same
4996 // name as the interfaceType
4998 // unknown interface type
5002 parentPrivate
->hidden
= childPrivate
->hidden
;
5004 if (childPrivate
->overrides
!= NULL
) {
5005 parentPrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, childPrivate
->overrides
);
5008 // The following change handles the case where a user has both an Ethernet and
5009 // PPPoE network service. Because a PPPoE service is typically associated with
5010 // an ISP we want it to be sorted higher in the service order.
5011 if ((parentPrivate
->entity_subtype
!= NULL
) &&
5012 (CFEqual(parentPrivate
->entity_subtype
, kSCValNetInterfaceSubTypePPPoE
))) {
5013 if ((childPrivate
->interface_type
!= NULL
) &&
5014 (CFEqual(childPrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
))) {
5015 parentPrivate
->sort_order
= kSortAirportPPP
;
5017 parentPrivate
->sort_order
= kSortEthernetPPP
;
5020 // set sort order of the parent to match the child interface
5021 parentPrivate
->sort_order
= childPrivate
->sort_order
;
5024 return (SCNetworkInterfaceRef
)parentPrivate
;
5028 CFRelease(parentPrivate
);
5029 _SCErrorSet(kSCStatusInvalidArgument
);
5036 __SCNetworkInterfaceGetDefaultConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
)
5038 CFDictionaryRef config
= NULL
;
5039 CFStringRef defaultType
;
5040 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5042 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5043 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5045 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5046 if (defaultType
!= NULL
) {
5050 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
5051 SCNetworkSetGetSetID(set
), // set
5052 interfacePrivate
->entity_device
, // interface
5053 defaultType
); // entity
5055 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
5058 if (config
== NULL
) {
5059 // if the "set" does not have a saved configuration, use
5060 // the [template] "interface" configuration
5061 if (interfacePrivate
->unsaved
!= NULL
) {
5062 config
= CFDictionaryGetValue(interfacePrivate
->unsaved
, defaultType
);
5063 if (config
== (CFDictionaryRef
)kCFNull
) {
5068 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5079 static CFDictionaryRef
5080 __SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface
,
5081 CFStringRef extendedType
)
5083 CFDictionaryRef config
= NULL
;
5084 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5087 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5088 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5090 paths
= copyConfigurationPaths(interfacePrivate
, extendedType
);
5091 if (paths
!= NULL
) {
5094 path
= CFArrayGetValueAtIndex(paths
, 0);
5095 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
5099 if (interfacePrivate
->unsaved
!= NULL
) {
5100 config
= CFDictionaryGetValue(interfacePrivate
->unsaved
, extendedType
);
5101 if (config
== (CFDictionaryRef
)kCFNull
) {
5107 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5116 SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface
)
5118 CFDictionaryRef config
;
5119 CFStringRef defaultType
;
5121 if (!isA_SCNetworkInterface(interface
)) {
5122 _SCErrorSet(kSCStatusInvalidArgument
);
5126 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5127 if (defaultType
== NULL
) {
5131 config
= __SCNetworkInterfaceGetConfiguration(interface
, defaultType
);
5132 if (config
== NULL
) {
5133 if (CFEqual(defaultType
, kSCEntNetAirPort
)) {
5134 SCNetworkInterfacePrivateRef interfacePrivate
;
5137 // if AirPort interface, check for a per-service config
5138 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5139 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
5140 interfacePrivate
->serviceID
, // service
5141 kSCEntNetAirPort
); // entity
5142 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
5146 if (config
== NULL
) {
5147 _SCErrorSet(kSCStatusOK
);
5155 SCNetworkInterfaceGetExtendedConfiguration(SCNetworkInterfaceRef interface
,
5156 CFStringRef extendedType
)
5158 CFDictionaryRef config
;
5160 if (!isA_SCNetworkInterface(interface
)) {
5161 _SCErrorSet(kSCStatusInvalidArgument
);
5165 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, TRUE
)) {
5166 _SCErrorSet(kSCStatusInvalidArgument
);
5170 config
= __SCNetworkInterfaceGetConfiguration(interface
, extendedType
);
5171 if (config
== NULL
) {
5172 _SCErrorSet(kSCStatusOK
);
5181 __SCNetworkInterfaceGetEntityType(SCNetworkInterfaceRef interface
)
5183 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5185 return interfacePrivate
->entity_type
;
5191 __SCNetworkInterfaceGetEntitySubType(SCNetworkInterfaceRef interface
)
5193 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
) interface
;
5195 return interfacePrivate
->entity_subtype
;
5200 SCNetworkInterfaceGetBSDName(SCNetworkInterfaceRef interface
)
5202 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5204 if (!isA_SCNetworkInterface(interface
)) {
5205 _SCErrorSet(kSCStatusInvalidArgument
);
5209 if ((interfacePrivate
->interface
!= NULL
) &&
5210 (interfacePrivate
->interface
!= kSCNetworkInterfaceIPv4
)) {
5211 _SCErrorSet(kSCStatusOK
);
5215 return interfacePrivate
->entity_device
;
5220 SCNetworkInterfaceGetHardwareAddressString(SCNetworkInterfaceRef interface
)
5222 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5224 if (!isA_SCNetworkInterface(interface
)) {
5225 _SCErrorSet(kSCStatusInvalidArgument
);
5229 if ((interfacePrivate
->address
!= NULL
) &&
5230 (interfacePrivate
->addressString
== NULL
)) {
5234 char mac
[sizeof("xx:xx:xx:xx:xx:xx:xx:xx")];
5237 bp
= (uint8_t *)CFDataGetBytePtr(interfacePrivate
->address
);
5238 n
= CFDataGetLength(interfacePrivate
->address
) * 3;
5240 if (n
> sizeof(mac
)) {
5241 mac_p
= CFAllocatorAllocate(NULL
, 0, n
);
5244 for (cp
= mac_p
; n
> 0; n
-= 3) {
5245 cp
+= snprintf(cp
, n
, "%2.2x:", *bp
++);
5248 interfacePrivate
->addressString
= CFStringCreateWithCString(NULL
, mac_p
, kCFStringEncodingUTF8
);
5249 if (mac_p
!= mac
) CFAllocatorDeallocate(NULL
, mac_p
);
5252 return interfacePrivate
->addressString
;
5256 SCNetworkInterfaceRef
5257 SCNetworkInterfaceGetInterface(SCNetworkInterfaceRef interface
)
5259 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5261 if (!isA_SCNetworkInterface(interface
)) {
5262 _SCErrorSet(kSCStatusInvalidArgument
);
5266 return interfacePrivate
->interface
;
5271 SCNetworkInterfaceGetInterfaceType(SCNetworkInterfaceRef interface
)
5273 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5275 if (!isA_SCNetworkInterface(interface
)) {
5276 _SCErrorSet(kSCStatusInvalidArgument
);
5280 return interfacePrivate
->interface_type
;
5285 copy_string_from_bundle(CFBundleRef bundle
, CFStringRef key
, Boolean localized
)
5287 CFStringRef str
= NULL
;
5290 str
= CFBundleCopyLocalizedString(bundle
,
5293 NETWORKINTERFACE_LOCALIZATIONS
);
5295 str
= _SC_CFBundleCopyNonLocalizedString(bundle
,
5298 NETWORKINTERFACE_LOCALIZATIONS
);
5306 copy_interface_string(CFBundleRef bundle
, CFStringRef key
, Boolean localized
)
5308 static Boolean reported
= FALSE
;
5309 CFStringRef str
= NULL
;
5311 str
= copy_string_from_bundle(bundle
, key
, localized
);
5314 SC_log(LOG_ERR
, "Received NULL string for the interface key: {Bundle: %@, key: %@, localized: %d}", bundle
,
5320 if (CFEqual(str
, key
) && !reported
) {
5321 const CFStringRef knownStrKey
= CFSTR("airport");
5322 CFStringRef knownStrValue
= NULL
;
5324 knownStrValue
= copy_string_from_bundle(bundle
, knownStrKey
, localized
);
5325 if (knownStrValue
== NULL
|| CFEqual(knownStrValue
, knownStrKey
)) {
5326 /* We are here because we requested for a localized/non-localized string
5327 based on the localization key, but we were given the same key/NULL back,
5328 implying a bad...bad thing!
5330 SC_log(LOG_ERR
, "Failed to retrieve the interface string: {Bundle: %@, key: %@, localized: %d}", bundle
,
5334 #if TARGET_OS_IPHONE
5335 /* ...and we want to know about it! */
5336 _SC_crash("Failed to retrieve interface string", NULL
, NULL
);
5337 #endif //TARGET_OS_IPHONE
5341 if (knownStrValue
!= NULL
) {
5342 CFRelease(knownStrValue
);
5352 copy_display_name(SCNetworkInterfaceRef interface
, Boolean localized
, Boolean oldLocalization
)
5354 CFMutableStringRef local
;
5357 local
= CFStringCreateMutable(NULL
, 0);
5359 while (interface
!= NULL
) {
5360 Boolean added
= FALSE
;
5361 SCNetworkInterfaceRef child
= NULL
;
5362 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5364 if ((interfacePrivate
->interface
!= NULL
) &&
5365 (interfacePrivate
->interface
!= kSCNetworkInterfaceIPv4
) &&
5366 !CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeVPN
)) {
5367 child
= interfacePrivate
->interface
;
5370 if ((bundle
!= NULL
) && (interfacePrivate
->localized_key
!= NULL
)) {
5372 CFStringRef key
= interfacePrivate
->localized_key
;
5374 if (oldLocalization
) {
5375 key
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("X-%@"),
5376 interfacePrivate
->localized_key
);
5378 fmt
= copy_interface_string(bundle
, key
, localized
);
5380 CFStringAppendFormat(local
,
5383 interfacePrivate
->localized_arg1
,
5384 interfacePrivate
->localized_arg2
);
5388 if (oldLocalization
) {
5394 (interfacePrivate
->prefs
!= NULL
) &&
5395 (interfacePrivate
->serviceID
!= NULL
) &&
5397 CFDictionaryRef entity
;
5400 // check for (and use) the name of the interface when it
5401 // was last available
5402 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,
5403 interfacePrivate
->serviceID
,
5404 kSCEntNetInterface
);
5405 entity
= SCPreferencesPathGetValue(interfacePrivate
->prefs
, path
);
5407 if (isA_CFDictionary(entity
)) {
5410 name
= CFDictionaryGetValue(entity
, kSCPropUserDefinedName
);
5411 if (isA_CFString(name
)) {
5412 CFStringAppend(local
, name
);
5419 // create (non-)localized name based on the interface type
5420 CFStringAppend(local
, interfacePrivate
->interface_type
);
5422 // ... and, if this is a leaf node, the interface device
5423 if ((interfacePrivate
->entity_device
!= NULL
) && (child
== NULL
)) {
5424 CFStringAppendFormat(local
, NULL
, CFSTR(" (%@)"), interfacePrivate
->entity_device
);
5428 if (child
!= NULL
) {
5429 // if this interface is layered over another
5430 CFStringAppend(local
, CFSTR(" --> "));
5436 name
= CFStringCreateCopy(NULL
, local
);
5443 #if !TARGET_OS_IPHONE
5446 __SCNetworkInterfaceCopyXLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5450 if (!isA_SCNetworkInterface(interface
)) {
5451 _SCErrorSet(kSCStatusInvalidArgument
);
5455 name
= copy_display_name(interface
, TRUE
, TRUE
);
5462 __SCNetworkInterfaceCopyXNonLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5464 CFStringRef localized_name
;
5466 if (!isA_SCNetworkInterface(interface
)) {
5467 _SCErrorSet(kSCStatusInvalidArgument
);
5471 localized_name
= copy_display_name(interface
, FALSE
, TRUE
);
5472 return localized_name
;
5474 #endif // !TARGET_OS_IPHONE
5478 __SCNetworkInterfaceSetUserDefinedName(SCNetworkInterfaceRef interface
, CFStringRef name
)
5480 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5482 if (!isA_SCNetworkInterface(interface
)) {
5488 if (interfacePrivate
->name
!= NULL
) {
5489 CFRelease(interfacePrivate
->name
);
5491 interfacePrivate
->name
= name
;
5496 if (interfacePrivate
->localized_name
!= NULL
) {
5497 CFRelease(interfacePrivate
->localized_name
);
5499 interfacePrivate
->localized_name
= name
;
5504 __SCNetworkInterfaceGetUserDefinedName(SCNetworkInterfaceRef interface
)
5506 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5508 if (!isA_SCNetworkInterface(interface
)) {
5512 return interfacePrivate
->name
;
5518 __SCNetworkInterfaceGetNonLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5520 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5522 if (!isA_SCNetworkInterface(interface
)) {
5523 _SCErrorSet(kSCStatusInvalidArgument
);
5527 if (interfacePrivate
->name
== NULL
) {
5528 interfacePrivate
->name
= copy_display_name(interface
, FALSE
, FALSE
);
5531 return interfacePrivate
->name
;
5536 SCNetworkInterfaceGetLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5538 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5540 if (!isA_SCNetworkInterface(interface
)) {
5541 _SCErrorSet(kSCStatusInvalidArgument
);
5545 if (interfacePrivate
->localized_name
== NULL
) {
5546 interfacePrivate
->localized_name
= copy_display_name(interface
, TRUE
, FALSE
);
5549 return interfacePrivate
->localized_name
;
5555 __SCNetworkInterfaceGetTemplateOverrides(SCNetworkInterfaceRef interface
, CFStringRef overrideType
)
5557 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5558 CFDictionaryRef overrides
= NULL
;
5560 if (interfacePrivate
->overrides
!= NULL
) {
5561 overrides
= CFDictionaryGetValue(interfacePrivate
->overrides
, overrideType
);
5569 SCNetworkInterfaceGetTypeID(void)
5571 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
); /* initialize runtime */
5572 return __kSCNetworkInterfaceTypeID
;
5578 __SCNetworkInterfaceSetDefaultConfiguration(SCNetworkSetRef set
,
5579 SCNetworkInterfaceRef interface
,
5580 CFStringRef defaultType
,
5581 CFDictionaryRef config
,
5584 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5587 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5588 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5590 if (defaultType
== NULL
) {
5591 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5592 if (defaultType
== NULL
) {
5597 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5604 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
5605 SCNetworkSetGetSetID(set
), // set
5606 interfacePrivate
->entity_device
, // interface
5607 defaultType
); // entity
5609 ok
= __setPrefsConfiguration(interfacePrivate
->prefs
, path
, config
, FALSE
);
5612 // if configuration has been saved
5613 if (interfacePrivate
->unsaved
!= NULL
) {
5614 CFDictionaryRemoveValue(interfacePrivate
->unsaved
, defaultType
);
5615 if (CFDictionaryGetCount(interfacePrivate
->unsaved
) == 0) {
5616 CFRelease(interfacePrivate
->unsaved
);
5617 interfacePrivate
->unsaved
= NULL
;
5623 if (config
== NULL
) {
5624 // remember that we are clearing the configuration
5625 config
= (CFDictionaryRef
)kCFNull
;
5628 if (interfacePrivate
->unsaved
== NULL
) {
5629 interfacePrivate
->unsaved
= CFDictionaryCreateMutable(NULL
,
5631 &kCFTypeDictionaryKeyCallBacks
,
5632 &kCFTypeDictionaryValueCallBacks
);
5634 CFDictionarySetValue(interfacePrivate
->unsaved
, defaultType
, config
);
5637 _SCErrorSet(kSCStatusNoKey
);
5648 __SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface
,
5649 CFStringRef extendedType
,
5650 CFDictionaryRef config
,
5653 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5657 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5658 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5660 if (extendedType
== NULL
) {
5661 extendedType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5662 if (extendedType
== NULL
) {
5667 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5671 paths
= copyConfigurationPaths(interfacePrivate
, extendedType
);
5672 if (paths
!= NULL
) {
5676 n
= CFArrayGetCount(paths
);
5677 for (i
= 0; i
< n
; i
++) {
5680 path
= CFArrayGetValueAtIndex(paths
, i
);
5681 ok
= __setPrefsConfiguration(interfacePrivate
->prefs
, path
, config
, FALSE
);
5688 // if configuration has been saved
5689 if (interfacePrivate
->unsaved
!= NULL
) {
5690 CFDictionaryRemoveValue(interfacePrivate
->unsaved
, extendedType
);
5691 if (CFDictionaryGetCount(interfacePrivate
->unsaved
) == 0) {
5692 CFRelease(interfacePrivate
->unsaved
);
5693 interfacePrivate
->unsaved
= NULL
;
5701 if (config
== NULL
) {
5702 // remember that we are clearing the configuration
5703 config
= (CFDictionaryRef
)kCFNull
;
5706 if (interfacePrivate
->unsaved
== NULL
) {
5707 interfacePrivate
->unsaved
= CFDictionaryCreateMutable(NULL
,
5709 &kCFTypeDictionaryKeyCallBacks
,
5710 &kCFTypeDictionaryValueCallBacks
);
5712 CFDictionarySetValue(interfacePrivate
->unsaved
, extendedType
, config
);
5715 _SCErrorSet(kSCStatusNoKey
);
5724 SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface
, CFDictionaryRef config
)
5726 CFStringRef defaultType
;
5728 if (!isA_SCNetworkInterface(interface
)) {
5729 _SCErrorSet(kSCStatusInvalidArgument
);
5733 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5734 if (defaultType
== NULL
) {
5738 return __SCNetworkInterfaceSetConfiguration(interface
, defaultType
, config
, FALSE
);
5743 SCNetworkInterfaceSetExtendedConfiguration(SCNetworkInterfaceRef interface
,
5744 CFStringRef extendedType
,
5745 CFDictionaryRef config
)
5747 if (!isA_SCNetworkInterface(interface
)) {
5748 _SCErrorSet(kSCStatusInvalidArgument
);
5752 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, TRUE
)) {
5756 return __SCNetworkInterfaceSetConfiguration(interface
, extendedType
, config
, FALSE
);
5761 #pragma mark SCNetworkInterface [Refresh Configuration] API
5764 #ifndef kSCEntNetRefreshConfiguration
5765 #define kSCEntNetRefreshConfiguration CFSTR("RefreshConfiguration")
5766 #endif // kSCEntNetRefreshConfiguration
5769 _SCNetworkInterfaceForceConfigurationRefresh(CFStringRef ifName
)
5774 if (!isA_CFString(ifName
)) {
5775 _SCErrorSet(kSCStatusInvalidArgument
);
5779 key
= SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL
,
5780 kSCDynamicStoreDomainState
,
5782 kSCEntNetRefreshConfiguration
);
5783 ok
= SCDynamicStoreNotifyValue(NULL
, key
);
5790 __SCNetworkInterfaceForceConfigurationRefresh_helper(SCPreferencesRef prefs
, CFStringRef ifName
)
5792 CFDataRef data
= NULL
;
5794 SCPreferencesPrivateRef prefsPrivate
= (SCPreferencesPrivateRef
)prefs
;
5795 uint32_t status
= kSCStatusOK
;
5796 CFDataRef reply
= NULL
;
5798 if (prefsPrivate
->helper_port
== MACH_PORT_NULL
) {
5799 ok
= __SCPreferencesCreate_helper(prefs
);
5805 // serialize the interface name
5806 ok
= _SCSerializeString(ifName
, &data
, NULL
, NULL
);
5811 // have the helper "refresh" the configuration
5812 status
= kSCStatusOK
;
5814 ok
= _SCHelperExec(prefsPrivate
->helper_port
,
5815 SCHELPER_MSG_INTERFACE_REFRESH
,
5819 if (data
!= NULL
) CFRelease(data
);
5824 if (status
!= kSCStatusOK
) {
5833 if (prefsPrivate
->helper_port
!= MACH_PORT_NULL
) {
5834 _SCHelperClose(&prefsPrivate
->helper_port
);
5837 status
= kSCStatusAccessError
;
5842 _SCErrorSet(status
);
5848 SCNetworkInterfaceForceConfigurationRefresh(SCNetworkInterfaceRef interface
)
5851 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5853 if (!isA_SCNetworkInterface(interface
)) {
5854 _SCErrorSet(kSCStatusInvalidArgument
);
5858 ifName
= SCNetworkInterfaceGetBSDName(interface
);
5859 if (ifName
== NULL
) {
5860 _SCErrorSet(kSCStatusInvalidArgument
);
5864 if (interfacePrivate
->prefs
!= NULL
) {
5865 SCPreferencesRef prefs
= interfacePrivate
->prefs
;
5866 SCPreferencesPrivateRef prefsPrivate
= (SCPreferencesPrivateRef
)prefs
;
5868 if (prefsPrivate
->authorizationData
!= NULL
) {
5869 return __SCNetworkInterfaceForceConfigurationRefresh_helper(prefs
, ifName
);
5873 return _SCNetworkInterfaceForceConfigurationRefresh(ifName
);
5878 SCNetworkInterfaceRefreshConfiguration(CFStringRef ifName
)
5880 return _SCNetworkInterfaceForceConfigurationRefresh(ifName
);
5885 #pragma mark SCNetworkInterface Password APIs
5889 getPasswordID(CFDictionaryRef config
, CFStringRef serviceID
)
5891 CFStringRef unique_id
= NULL
;
5893 if (config
!= NULL
) {
5894 CFStringRef encryption
;
5896 encryption
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPasswordEncryption
);
5897 if (isA_CFString(encryption
) &&
5898 CFEqual(encryption
, kSCValNetPPPAuthPasswordEncryptionKeychain
)) {
5899 unique_id
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPassword
);
5902 if (unique_id
== NULL
) {
5903 unique_id
= serviceID
;
5911 copySharedSecretID(CFDictionaryRef config
, CFStringRef serviceID
)
5913 CFMutableStringRef shared_id
= NULL
;
5915 if (config
!= NULL
) {
5916 CFStringRef encryption
;
5918 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecretEncryption
);
5919 if (isA_CFString(encryption
) &&
5920 CFEqual(encryption
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) {
5921 shared_id
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecret
);
5922 if (shared_id
!= NULL
) {
5923 CFRetain(shared_id
);
5928 if (shared_id
== NULL
) {
5929 CFStringRef unique_id
;
5931 unique_id
= getPasswordID(config
, serviceID
);
5932 shared_id
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
5933 CFStringAppend(shared_id
, CFSTR(".SS"));
5941 copyXAuthID(CFDictionaryRef config
, CFStringRef serviceID
)
5943 CFMutableStringRef xauth_id
= NULL
;
5945 if (config
!= NULL
) {
5946 CFStringRef encryption
;
5948 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPasswordEncryption
);
5949 if (isA_CFString(encryption
) &&
5950 CFEqual(encryption
, kSCValNetIPSecXAuthPasswordEncryptionKeychain
)) {
5951 xauth_id
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPassword
);
5952 if (xauth_id
!= NULL
) {
5958 if (xauth_id
== NULL
) {
5959 CFStringRef unique_id
;
5961 unique_id
= getPasswordID(config
, serviceID
);
5962 xauth_id
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
5963 CFStringAppend(xauth_id
, CFSTR(".XAUTH"));
5971 checkInterfacePassword(SCNetworkInterfaceRef interface
,
5972 SCNetworkInterfacePasswordType passwordType
,
5973 SCPreferencesRef
*prefs
,
5974 CFStringRef
*serviceID
)
5976 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5978 if (!isA_SCNetworkInterface(interface
)) {
5982 *serviceID
= interfacePrivate
->serviceID
;
5983 if (*serviceID
== NULL
) {
5987 *prefs
= interfacePrivate
->prefs
;
5988 if (*prefs
== NULL
) {
5992 switch (passwordType
) {
5993 case kSCNetworkInterfacePasswordTypePPP
: {
5994 CFStringRef interfaceType
;
5996 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
5997 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
6005 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6006 CFStringRef interfaceType
;
6008 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
6009 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
6010 interface
= SCNetworkInterfaceGetInterface(interface
);
6011 if (interface
!= NULL
) {
6012 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
6013 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
6014 // if PPP->L2TP interface
6018 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
6019 // if IPSec interface
6026 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6030 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6031 CFStringRef interfaceType
;
6033 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
6034 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
6035 // if IPSec interface
6042 case kSCNetworkInterfacePasswordTypeVPN
: {
6043 CFStringRef interfaceType
;
6045 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
6046 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) {
6062 _SCErrorSet(kSCStatusInvalidArgument
);
6068 SCNetworkInterfaceCheckPassword(SCNetworkInterfaceRef interface
,
6069 SCNetworkInterfacePasswordType passwordType
)
6071 Boolean exists
= FALSE
;
6072 SCPreferencesRef prefs
= NULL
;
6073 CFStringRef serviceID
= NULL
;
6075 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6079 switch (passwordType
) {
6080 case kSCNetworkInterfacePasswordTypePPP
: {
6081 CFDictionaryRef config
;
6082 CFStringRef unique_id
;
6084 // get configuration
6085 config
= SCNetworkInterfaceGetConfiguration(interface
);
6088 unique_id
= getPasswordID(config
, serviceID
);
6091 exists
= __extract_password(prefs
,
6093 kSCPropNetPPPAuthPassword
,
6094 kSCPropNetPPPAuthPasswordEncryption
,
6095 kSCValNetPPPAuthPasswordEncryptionKeychain
,
6101 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6102 CFDictionaryRef config
;
6104 CFStringRef shared_id
;
6106 // get configuration
6107 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6109 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6111 config
= SCNetworkInterfaceGetConfiguration(interface
);
6114 // get sharedSecret ID
6115 shared_id
= copySharedSecretID(config
, serviceID
);
6118 exists
= __extract_password(prefs
,
6120 kSCPropNetIPSecSharedSecret
,
6121 kSCPropNetIPSecSharedSecretEncryption
,
6122 kSCValNetIPSecSharedSecretEncryptionKeychain
,
6125 CFRelease(shared_id
);
6129 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6130 CFDictionaryRef config
;
6131 CFStringRef unique_id
= NULL
;
6133 // get configuration
6134 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6136 // get 802.1X identifier
6137 if (config
!= NULL
) {
6138 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6140 if (!isA_CFString(unique_id
)) {
6145 exists
= _SCPreferencesSystemKeychainPasswordItemExists(prefs
, unique_id
);
6149 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6150 CFDictionaryRef config
;
6151 CFStringRef xauth_id
;
6153 // get configuration
6154 config
= SCNetworkInterfaceGetConfiguration(interface
);
6157 xauth_id
= copyXAuthID(config
, serviceID
);
6160 exists
= __extract_password(prefs
,
6162 kSCPropNetIPSecXAuthPassword
,
6163 kSCPropNetIPSecXAuthPasswordEncryption
,
6164 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
6167 CFRelease(xauth_id
);
6171 case kSCNetworkInterfacePasswordTypeVPN
: {
6172 CFDictionaryRef config
;
6175 // get configuration
6176 config
= SCNetworkInterfaceGetConfiguration(interface
);
6179 vpn_id
= getPasswordID(config
, serviceID
);
6182 exists
= __extract_password(prefs
,
6184 kSCPropNetVPNAuthPassword
,
6185 kSCPropNetVPNAuthPasswordEncryption
,
6186 kSCValNetVPNAuthPasswordEncryptionKeychain
,
6193 _SCErrorSet(kSCStatusInvalidArgument
);
6202 SCNetworkInterfaceCopyPassword(SCNetworkInterfaceRef interface
,
6203 SCNetworkInterfacePasswordType passwordType
)
6205 CFDataRef password
= NULL
;
6206 SCPreferencesRef prefs
= NULL
;
6207 CFStringRef serviceID
= NULL
;
6209 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6213 switch (passwordType
) {
6214 case kSCNetworkInterfacePasswordTypePPP
: {
6215 CFDictionaryRef config
;
6216 CFStringRef unique_id
;
6218 // get configuration
6219 config
= SCNetworkInterfaceGetConfiguration(interface
);
6222 unique_id
= getPasswordID(config
, serviceID
);
6225 (void) __extract_password(prefs
,
6227 kSCPropNetPPPAuthPassword
,
6228 kSCPropNetPPPAuthPasswordEncryption
,
6229 kSCValNetPPPAuthPasswordEncryptionKeychain
,
6235 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6236 CFDictionaryRef config
;
6238 CFStringRef shared_id
;
6240 // get configuration
6241 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6243 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6245 config
= SCNetworkInterfaceGetConfiguration(interface
);
6248 // get sharedSecret ID
6249 shared_id
= copySharedSecretID(config
, serviceID
);
6252 (void) __extract_password(prefs
,
6254 kSCPropNetIPSecSharedSecret
,
6255 kSCPropNetIPSecSharedSecretEncryption
,
6256 kSCValNetIPSecSharedSecretEncryptionKeychain
,
6260 CFRelease(shared_id
);
6264 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6265 CFDictionaryRef config
;
6266 CFStringRef unique_id
= NULL
;
6268 // get configuration
6269 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6271 // get 802.1X identifier
6272 if (config
!= NULL
) {
6273 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6275 if (!isA_CFString(unique_id
)) {
6276 _SCErrorSet(kSCStatusFailed
);
6281 password
= _SCPreferencesSystemKeychainPasswordItemCopy(prefs
, unique_id
);
6285 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6286 CFDictionaryRef config
;
6287 CFStringRef xauth_id
;
6289 // get configuration
6290 config
= SCNetworkInterfaceGetConfiguration(interface
);
6293 xauth_id
= copyXAuthID(config
, serviceID
);
6296 (void) __extract_password(prefs
,
6298 kSCPropNetIPSecXAuthPassword
,
6299 kSCPropNetIPSecXAuthPasswordEncryption
,
6300 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
6303 CFRelease(xauth_id
);
6307 case kSCNetworkInterfacePasswordTypeVPN
: {
6308 CFDictionaryRef config
;
6311 // get configuration
6312 config
= SCNetworkInterfaceGetConfiguration(interface
);
6315 vpn_id
= getPasswordID(config
, serviceID
);
6318 (void) __extract_password(prefs
,
6320 kSCPropNetVPNAuthPassword
,
6321 kSCPropNetVPNAuthPasswordEncryption
,
6322 kSCValNetVPNAuthPasswordEncryptionKeychain
,
6329 _SCErrorSet(kSCStatusInvalidArgument
);
6338 SCNetworkInterfaceRemovePassword(SCNetworkInterfaceRef interface
,
6339 SCNetworkInterfacePasswordType passwordType
)
6342 SCPreferencesRef prefs
= NULL
;
6343 CFStringRef serviceID
= NULL
;
6345 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6349 switch (passwordType
) {
6350 case kSCNetworkInterfacePasswordTypePPP
: {
6351 CFDictionaryRef config
;
6352 CFDictionaryRef newConfig
= NULL
;
6353 CFStringRef unique_id
;
6355 // get configuration
6356 config
= SCNetworkInterfaceGetConfiguration(interface
);
6359 unique_id
= getPasswordID(config
, serviceID
);
6362 ok
= __remove_password(prefs
,
6364 kSCPropNetPPPAuthPassword
,
6365 kSCPropNetPPPAuthPasswordEncryption
,
6366 kSCValNetPPPAuthPasswordEncryptionKeychain
,
6370 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6371 if (newConfig
!= NULL
) CFRelease(newConfig
);
6377 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6378 CFDictionaryRef config
;
6380 CFDictionaryRef newConfig
= NULL
;
6381 CFStringRef shared_id
;
6383 // get configuration
6384 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6386 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6388 config
= SCNetworkInterfaceGetConfiguration(interface
);
6391 // get sharedSecret ID
6392 shared_id
= copySharedSecretID(config
, serviceID
);
6395 ok
= __remove_password(prefs
,
6397 kSCPropNetIPSecSharedSecret
,
6398 kSCPropNetIPSecSharedSecretEncryption
,
6399 kSCValNetIPSecSharedSecretEncryptionKeychain
,
6404 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
6408 ok
= SCNetworkInterfaceSetConfiguration(interface
,
6411 if (newConfig
!= NULL
) CFRelease(newConfig
);
6414 CFRelease(shared_id
);
6418 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6419 CFDictionaryRef config
;
6420 CFStringRef unique_id
= NULL
;
6422 // get configuration
6423 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6425 // get 802.1X identifier
6426 if (config
!= NULL
) {
6427 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6429 if (!isA_CFString(unique_id
)) {
6430 _SCErrorSet(kSCStatusFailed
);
6435 ok
= _SCPreferencesSystemKeychainPasswordItemRemove(prefs
, unique_id
);
6439 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6440 CFDictionaryRef config
;
6441 CFDictionaryRef newConfig
= NULL
;
6442 CFStringRef xauth_id
;
6444 // get configuration
6445 config
= SCNetworkInterfaceGetConfiguration(interface
);
6448 xauth_id
= copyXAuthID(config
, serviceID
);
6451 ok
= __remove_password(prefs
,
6453 kSCPropNetIPSecXAuthPassword
,
6454 kSCPropNetIPSecXAuthPasswordEncryption
,
6455 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
6459 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6460 if (newConfig
!= NULL
) CFRelease(newConfig
);
6463 CFRelease(xauth_id
);
6467 case kSCNetworkInterfacePasswordTypeVPN
: {
6468 CFDictionaryRef config
;
6469 CFDictionaryRef newConfig
= NULL
;
6472 // get configuration
6473 config
= SCNetworkInterfaceGetConfiguration(interface
);
6476 vpn_id
= getPasswordID(config
, serviceID
);
6479 ok
= __remove_password(prefs
,
6481 kSCPropNetVPNAuthPassword
,
6482 kSCPropNetVPNAuthPasswordEncryption
,
6483 kSCValNetVPNAuthPasswordEncryptionKeychain
,
6487 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6488 if (newConfig
!= NULL
) CFRelease(newConfig
);
6494 _SCErrorSet(kSCStatusInvalidArgument
);
6503 SCNetworkInterfaceSetPassword(SCNetworkInterfaceRef interface
,
6504 SCNetworkInterfacePasswordType passwordType
,
6506 CFDictionaryRef options
)
6508 CFStringRef account
= NULL
;
6509 CFDictionaryRef config
;
6510 CFStringRef description
= NULL
;
6511 CFStringRef label
= NULL
;
6513 SCPreferencesRef prefs
= NULL
;
6514 CFStringRef serviceID
= NULL
;
6516 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6520 switch (passwordType
) {
6521 case kSCNetworkInterfacePasswordTypePPP
: {
6522 SCNetworkServiceRef service
= NULL
;
6523 CFStringRef unique_id
;
6525 // get configuration
6526 config
= SCNetworkInterfaceGetConfiguration(interface
);
6529 unique_id
= getPasswordID(config
, serviceID
);
6531 // get "Account", "Name", "Kind"
6532 if (config
!= NULL
) {
6533 // auth name --> keychain "Account"
6534 account
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthName
);
6536 // PPP [user defined] "name" --> keychain "Name"
6537 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6540 if (label
== NULL
) {
6541 // service name --> keychain "Name"
6542 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
6547 label
= SCNetworkServiceGetName(service
);
6548 if (label
== NULL
) {
6549 // interface name --> keychain "Name"
6550 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6554 if (bundle
!= NULL
) {
6555 // "PPP Password" --> keychain "Kind"
6556 description
= CFBundleCopyLocalizedString(bundle
,
6557 CFSTR("KEYCHAIN_KIND_PPP_PASSWORD"),
6558 CFSTR("PPP Password"),
6563 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6565 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6566 (description
!= NULL
) ? description
: CFSTR("PPP Password"),
6571 CFMutableDictionaryRef newConfig
;
6573 if (config
!= NULL
) {
6574 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6576 newConfig
= CFDictionaryCreateMutable(NULL
,
6578 &kCFTypeDictionaryKeyCallBacks
,
6579 &kCFTypeDictionaryValueCallBacks
);
6581 CFDictionarySetValue(newConfig
,
6582 kSCPropNetPPPAuthPassword
,
6584 CFDictionarySetValue(newConfig
,
6585 kSCPropNetPPPAuthPasswordEncryption
,
6586 kSCValNetPPPAuthPasswordEncryptionKeychain
);
6587 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6588 CFRelease(newConfig
);
6591 if (description
!= NULL
) CFRelease(description
);
6592 if (service
!= NULL
) CFRelease(service
);
6596 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6597 CFDictionaryRef baseConfig
= NULL
;
6599 SCNetworkServiceRef service
= NULL
;
6600 CFStringRef shared_id
;
6602 // get configuration
6603 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6604 config
= SCNetworkInterfaceGetConfiguration(interface
);
6606 baseConfig
= config
;
6607 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6610 // get sharedSecret ID
6611 shared_id
= copySharedSecretID(config
, serviceID
);
6613 // get "Account", "Name", "Kind"
6614 if (config
!= NULL
) {
6615 CFStringRef localIdentifier
;
6616 CFStringRef localIdentifierType
;
6618 if (CFDictionaryGetValueIfPresent(config
,
6619 kSCPropNetIPSecLocalIdentifierType
,
6620 (const void **)&localIdentifierType
)
6621 && CFEqual(localIdentifierType
, kSCValNetIPSecLocalIdentifierTypeKeyID
)
6622 && CFDictionaryGetValueIfPresent(config
,
6623 kSCPropNetIPSecLocalIdentifier
,
6624 (const void **)&localIdentifier
)
6625 && isA_CFString(localIdentifier
)) {
6626 // local identifier --> keychain "Account"
6627 account
= localIdentifier
;
6630 // PPP [user defined] "name" --> keychain "Name"
6632 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6634 if (baseConfig
!= NULL
) {
6635 label
= CFDictionaryGetValue(baseConfig
, kSCPropUserDefinedName
);
6640 if (label
== NULL
) {
6641 // service name --> keychain "Name"
6642 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
6647 label
= SCNetworkServiceGetName(service
);
6648 if (label
== NULL
) {
6649 // interface name --> keychain "Name"
6650 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6654 if (bundle
!= NULL
) {
6655 // "IPSec Shared Secret" --> keychain "Kind"
6656 description
= CFBundleCopyLocalizedString(bundle
,
6657 CFSTR("KEYCHAIN_KIND_IPSEC_SHARED_SECRET"),
6658 CFSTR("IPSec Shared Secret"),
6663 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6665 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6666 (description
!= NULL
) ? description
: CFSTR("IPSec Shared Secret"),
6671 CFMutableDictionaryRef newConfig
= NULL
;
6673 if (config
!= NULL
) {
6674 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6676 newConfig
= CFDictionaryCreateMutable(NULL
,
6678 &kCFTypeDictionaryKeyCallBacks
,
6679 &kCFTypeDictionaryValueCallBacks
);
6681 CFDictionarySetValue(newConfig
,
6682 kSCPropNetIPSecSharedSecret
,
6684 CFDictionarySetValue(newConfig
,
6685 kSCPropNetIPSecSharedSecretEncryption
,
6686 kSCValNetIPSecSharedSecretEncryptionKeychain
);
6688 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
6692 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6694 CFRelease(newConfig
);
6697 if (description
!= NULL
) CFRelease(description
);
6698 if (service
!= NULL
) CFRelease(service
);
6699 CFRelease(shared_id
);
6703 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6704 CFStringRef account
= NULL
;
6705 CFStringRef unique_id
= NULL
;
6707 // get configuration
6708 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6710 // get 802.1X identifier
6711 if (config
!= NULL
) {
6712 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6713 unique_id
= isA_CFString(unique_id
);
6715 if (unique_id
!= NULL
) {
6716 CFRetain(unique_id
);
6720 uuid
= CFUUIDCreate(NULL
);
6721 unique_id
= CFUUIDCreateString(NULL
, uuid
);
6725 // 802.1x UserName --> keychain "Account"
6726 if (config
!= NULL
) {
6727 account
= CFDictionaryGetValue(config
, kEAPClientPropUserName
);
6730 // get "Name", "Kind"
6731 if (bundle
!= NULL
) {
6732 CFStringRef interface_name
;
6734 // "Network Connection (%@)" --> keychain "Name"
6735 interface_name
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6736 if (interface_name
!= NULL
) {
6737 CFStringRef label_fmt
;
6739 label_fmt
= CFBundleCopyLocalizedString(bundle
,
6740 CFSTR("KEYCHAIN_DESCRIPTION_EAPOL_INTERFACE"),
6741 CFSTR("Network Connection (%@)"),
6743 label
= CFStringCreateWithFormat(NULL
, NULL
, label_fmt
, interface_name
);
6744 CFRelease(label_fmt
);
6746 label
= CFBundleCopyLocalizedString(bundle
,
6747 CFSTR("KEYCHAIN_DESCRIPTION_EAPOL"),
6748 CFSTR("Network Connection"),
6752 // "802.1X Password" --> keychain "Kind"
6753 description
= CFBundleCopyLocalizedString(bundle
,
6754 CFSTR("KEYCHAIN_KIND_EAPOL"),
6755 CFSTR("802.1X Password"),
6760 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6762 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6763 (description
!= NULL
) ? description
: CFSTR("802.1X Password"),
6768 CFMutableDictionaryRef newConfig
= NULL
;
6770 if (config
!= NULL
) {
6771 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6773 newConfig
= CFDictionaryCreateMutable(NULL
,
6775 &kCFTypeDictionaryKeyCallBacks
,
6776 &kCFTypeDictionaryValueCallBacks
);
6778 CFDictionarySetValue(newConfig
,
6779 kEAPClientPropUserPasswordKeychainItemID
,
6781 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
6784 CFRelease(newConfig
);
6787 CFRelease(unique_id
);
6788 if (label
!= NULL
) CFRelease(label
);
6789 if (description
!= NULL
) CFRelease(description
);
6793 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6794 SCNetworkServiceRef service
= NULL
;
6795 CFStringRef xauth_id
;
6797 // get configuration
6798 config
= SCNetworkInterfaceGetConfiguration(interface
);
6801 xauth_id
= copyXAuthID(config
, serviceID
);
6803 // get "Account", "Name", "Kind"
6804 if (config
!= NULL
) {
6805 // auth name --> keychain "Account"
6806 account
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthName
);
6808 // IPSec [user defined] "name" --> keychain "Name"
6809 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6812 if (label
== NULL
) {
6813 // service name --> keychain "Name"
6814 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
6819 label
= SCNetworkServiceGetName(service
);
6820 if (label
== NULL
) {
6821 // interface name --> keychain "Name"
6822 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6826 if (bundle
!= NULL
) {
6827 // "IPSec XAuth Password" --> keychain "Kind"
6828 description
= CFBundleCopyLocalizedString(bundle
,
6829 CFSTR("KEYCHAIN_KIND_IPSEC_XAUTH_PASSWORD"),
6830 CFSTR("IPSec XAuth Password"),
6835 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6837 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6838 (description
!= NULL
) ? description
: CFSTR("IPSec XAuth Password"),
6843 CFMutableDictionaryRef newConfig
;
6845 if (config
!= NULL
) {
6846 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6848 newConfig
= CFDictionaryCreateMutable(NULL
,
6850 &kCFTypeDictionaryKeyCallBacks
,
6851 &kCFTypeDictionaryValueCallBacks
);
6853 CFDictionarySetValue(newConfig
,
6854 kSCPropNetIPSecXAuthPassword
,
6856 CFDictionarySetValue(newConfig
,
6857 kSCPropNetIPSecXAuthPasswordEncryption
,
6858 kSCValNetIPSecXAuthPasswordEncryptionKeychain
);
6859 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6860 CFRelease(newConfig
);
6863 CFRelease(xauth_id
);
6864 if (description
!= NULL
) CFRelease(description
);
6865 if (service
!= NULL
) CFRelease(service
);
6869 case kSCNetworkInterfacePasswordTypeVPN
: {
6870 SCNetworkServiceRef service
= NULL
;
6873 // get configuration
6874 config
= SCNetworkInterfaceGetConfiguration(interface
);
6877 vpn_id
= getPasswordID(config
, serviceID
);
6879 // get "Account", "Name", "Kind"
6880 if (config
!= NULL
) {
6881 // auth name --> keychain "Account"
6882 account
= CFDictionaryGetValue(config
, kSCPropNetVPNAuthName
);
6884 // VPN [user defined] "name" --> keychain "Name"
6885 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6888 if (label
== NULL
) {
6889 // service name --> keychain "Name"
6890 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
6895 label
= SCNetworkServiceGetName(service
);
6896 if (label
== NULL
) {
6897 // interface name --> keychain "Name"
6898 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6902 if (bundle
!= NULL
) {
6903 // "VPN Password" --> keychain "Kind"
6904 description
= CFBundleCopyLocalizedString(bundle
,
6905 CFSTR("KEYCHAIN_KIND_VPN_PASSWORD"),
6906 CFSTR("VPN Password"),
6911 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6913 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6914 (description
!= NULL
) ? description
: CFSTR("VPN Password"),
6919 CFMutableDictionaryRef newConfig
;
6921 if (config
!= NULL
) {
6922 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6924 newConfig
= CFDictionaryCreateMutable(NULL
,
6926 &kCFTypeDictionaryKeyCallBacks
,
6927 &kCFTypeDictionaryValueCallBacks
);
6929 CFDictionarySetValue(newConfig
,
6930 kSCPropNetVPNAuthPassword
,
6932 CFDictionarySetValue(newConfig
,
6933 kSCPropNetVPNAuthPasswordEncryption
,
6934 kSCValNetVPNAuthPasswordEncryptionKeychain
);
6935 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6936 CFRelease(newConfig
);
6939 if (description
!= NULL
) CFRelease(description
);
6940 if (service
!= NULL
) CFRelease(service
);
6945 _SCErrorSet(kSCStatusInvalidArgument
);
6954 #pragma mark SCNetworkInterface [InterfaceNamer] SPIs
6958 _SCNetworkInterfaceCopyInterfaceInfo(SCNetworkInterfaceRef interface
)
6960 CFMutableDictionaryRef info
;
6961 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6964 if (interface
== NULL
) {
6968 info
= CFDictionaryCreateMutable(NULL
,
6970 &kCFTypeDictionaryKeyCallBacks
,
6971 &kCFTypeDictionaryValueCallBacks
);
6973 // add non-localized interface name
6974 name
= __SCNetworkInterfaceGetNonLocalizedDisplayName(interface
);
6976 CFDictionaryAddValue(info
, kSCPropUserDefinedName
, name
);
6980 if ((interfacePrivate
->usb
.vid
!= NULL
) || (interfacePrivate
->usb
.pid
!= NULL
)) {
6981 #if !TARGET_IPHONE_SIMULATOR
6982 if (interfacePrivate
->usb
.name
!= NULL
) {
6983 CFDictionaryAddValue(info
, CFSTR(kUSBProductString
), interfacePrivate
->usb
.name
);
6985 if (interfacePrivate
->usb
.vid
!= NULL
) {
6986 CFDictionaryAddValue(info
, CFSTR(kUSBVendorID
), interfacePrivate
->usb
.vid
);
6988 if (interfacePrivate
->usb
.pid
!= NULL
) {
6989 CFDictionaryAddValue(info
, CFSTR(kUSBProductID
), interfacePrivate
->usb
.pid
);
6991 #endif // !TARGET_IPHONE_SIMULATOR
6994 if (CFDictionaryGetCount(info
) == 0) {
6995 // do not return an empty dictionary
7004 SCNetworkInterfaceRef
7005 _SCNetworkInterfaceCreateWithIONetworkInterfaceObject(io_object_t if_obj
)
7007 SCNetworkInterfaceRef interface
= NULL
;
7009 /* initialize runtime */
7010 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
7012 if (IOObjectConformsTo(if_obj
, kIONetworkInterfaceClass
)) {
7013 interface
= createInterface(if_obj
, processNetworkInterface
, NULL
);
7014 } else if (IOObjectConformsTo(if_obj
, kIOSerialBSDServiceValue
)) {
7015 interface
= createInterface(if_obj
, processSerialInterface
, kSCNetworkInterfaceHiddenPortKey
);
7023 _SCNetworkInterfaceGetConfigurationAction(SCNetworkInterfaceRef interface
)
7025 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7027 return interfacePrivate
->configurationAction
;
7032 _SCNetworkInterfaceGetHardwareAddress(SCNetworkInterfaceRef interface
)
7034 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7036 return interfacePrivate
->address
;
7041 _SCNetworkInterfaceGetIOInterfaceNamePrefix(SCNetworkInterfaceRef interface
)
7043 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7045 return interfacePrivate
->prefix
;
7050 _SCNetworkInterfaceGetIOInterfaceType(SCNetworkInterfaceRef interface
)
7052 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7054 return interfacePrivate
->type
;
7059 _SCNetworkInterfaceGetIOInterfaceUnit(SCNetworkInterfaceRef interface
)
7061 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7063 return interfacePrivate
->unit
;
7068 _SCNetworkInterfaceGetIOPath(SCNetworkInterfaceRef interface
)
7070 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7072 return interfacePrivate
->path
;
7077 _SCNetworkInterfaceGetIORegistryEntryID(SCNetworkInterfaceRef interface
)
7079 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7081 return interfacePrivate
->entryID
;
7087 __SCNetworkInterfaceIsActive (SCNetworkInterfaceRef interface
)
7089 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7091 return interfacePrivate
->active
;
7096 _SCNetworkInterfaceIsBuiltin(SCNetworkInterfaceRef interface
)
7098 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7100 return interfacePrivate
->builtin
;
7105 #pragma mark SCNetworkInterface SPIs
7108 #if !TARGET_OS_EMBEDDED
7110 SCNetworkInterfaceRef
7111 _SCNetworkInterfaceCopyBTPANInterface(void)
7113 CFDictionaryRef dict
;
7114 SCNetworkInterfaceRef interface
= NULL
;
7117 key
= SCDynamicStoreKeyCreate(NULL
, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin
);
7118 dict
= SCDynamicStoreCopyValue(NULL
, key
);
7122 CFStringRef if_name
;
7123 SCNetworkInterfacePrivateRef interfacePrivate
;
7125 if (isA_CFDictionary(dict
) &&
7126 CFDictionaryGetValueIfPresent(dict
,
7127 CFSTR("_" BT_PAN_NAME
"_"),
7128 (const void **)&if_name
) &&
7129 isA_CFString(if_name
)) {
7130 CFMutableDictionaryRef entity
;
7132 entity
= CFDictionaryCreateMutable(NULL
,
7134 &kCFTypeDictionaryKeyCallBacks
,
7135 &kCFTypeDictionaryValueCallBacks
);
7136 CFDictionarySetValue(entity
,
7137 kSCPropNetInterfaceType
,
7138 kSCValNetInterfaceTypeEthernet
);
7139 CFDictionarySetValue(entity
,
7140 kSCPropNetInterfaceDeviceName
,
7142 CFDictionarySetValue(entity
,
7143 kSCPropUserDefinedName
,
7144 CFSTR(BT_PAN_NAME
));
7145 interface
= _SCNetworkInterfaceCreateWithEntity(NULL
, entity
, NULL
);
7149 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7151 if ((interfacePrivate
!= NULL
) &&
7152 (interfacePrivate
->address
== NULL
) &&
7153 CFDictionaryGetValueIfPresent(dict
,
7154 CFSTR("_" BT_PAN_MAC
"_"),
7155 (const void **)&addr
) &&
7157 interfacePrivate
->address
= CFRetain(addr
);
7165 #endif // !TARGET_OS_EMBEDDED
7169 _SCNetworkInterfaceCopySlashDevPath(SCNetworkInterfaceRef interface
)
7171 io_registry_entry_t device
;
7172 io_iterator_t device_iterator
= MACH_PORT_NULL
;
7173 CFStringRef device_path
= NULL
;
7174 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7176 CFStringRef match_keys
[2];
7177 CFTypeRef match_vals
[2];
7178 CFDictionaryRef match_dict
;
7179 CFDictionaryRef matching
;
7181 if (interfacePrivate
->entity_device
== NULL
) {
7185 if (interfacePrivate
->entity_device_unique
== NULL
) {
7189 match_keys
[0] = CFSTR(kIOTTYBaseNameKey
);
7190 match_vals
[0] = interfacePrivate
->entity_device
;
7191 match_dict
= CFDictionaryCreate(NULL
,
7192 (const void **)match_keys
,
7193 (const void **)match_vals
,
7195 &kCFTypeDictionaryKeyCallBacks
,
7196 &kCFTypeDictionaryValueCallBacks
);
7198 match_keys
[0] = CFSTR(kIOProviderClassKey
);
7199 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
7200 match_keys
[1] = CFSTR(kIOPropertyMatchKey
);
7201 match_vals
[1] = match_dict
;
7202 matching
= CFDictionaryCreate(NULL
,
7203 (const void **)match_keys
,
7204 (const void **)match_vals
,
7205 sizeof(match_keys
)/sizeof(match_keys
[0]),
7206 &kCFTypeDictionaryKeyCallBacks
,
7207 &kCFTypeDictionaryValueCallBacks
);
7208 CFRelease(match_dict
);
7210 // note: this "matching" dictionary will be consumed by the call to IOServiceGetMatchingServices
7211 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &device_iterator
);
7212 if (kr
!= kIOReturnSuccess
) {
7213 SC_log(LOG_INFO
, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr
);
7217 while ((device_path
== NULL
) &&
7218 ((device
= IOIteratorNext(device_iterator
)) != MACH_PORT_NULL
)) {
7219 CFDictionaryRef overrides
;
7221 overrides
= IORegistryEntrySearchCFProperty(device
,
7223 kSCNetworkInterfaceNetworkConfigurationOverridesKey
,
7225 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
7226 if (overrides
!= NULL
) {
7227 CFDictionaryRef modemOverrides
;
7229 modemOverrides
= CFDictionaryGetValue(overrides
, kSCEntNetModem
);
7230 if (modemOverrides
!= NULL
) {
7231 CFRetain(modemOverrides
);
7233 CFRelease(overrides
);
7234 overrides
= modemOverrides
;
7236 if (overrides
== NULL
) {
7237 overrides
= IORegistryEntrySearchCFProperty(device
,
7239 CFSTR("DeviceModemOverrides"),
7241 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
7243 if (overrides
!= NULL
) {
7244 if (isA_CFDictionary(overrides
)) {
7245 CFStringRef matchIdentifier
;
7247 matchIdentifier
= CFDictionaryGetValue(overrides
, CFSTR("UniqueIdentifier"));
7248 if (isA_CFString(matchIdentifier
) &&
7249 CFEqual(interfacePrivate
->entity_device_unique
, matchIdentifier
)) {
7250 device_path
= IORegistryEntryCreateCFProperty(device
,
7251 CFSTR(kIOTTYDeviceKey
),
7256 CFRelease(overrides
);
7258 IOObjectRelease(device
);
7261 IOObjectRelease(device_iterator
);
7265 if (device_path
== NULL
) {
7266 // if we haven't found an exact match to our UniqueIdentifier
7267 // so we simply return the base name.
7268 device_path
= SCNetworkInterfaceGetBSDName(interface
);
7269 if (device_path
!= NULL
) {
7270 CFRetain(device_path
);
7279 _SCNetworkInterfaceIsBluetoothPAN(SCNetworkInterfaceRef interface
)
7281 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7283 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_GN
);
7288 _SCNetworkInterfaceIsBluetoothPAN_NAP(SCNetworkInterfaceRef interface
)
7290 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7292 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_NAP
);
7297 _SCNetworkInterfaceIsBluetoothP2P(SCNetworkInterfaceRef interface
)
7299 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7301 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_U
);
7306 _SCNetworkInterfaceIsHiddenConfiguration(SCNetworkInterfaceRef interface
)
7308 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7310 return interfacePrivate
->hidden
;
7315 _SCNetworkInterfaceIsModemV92(SCNetworkInterfaceRef interface
)
7317 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7319 return interfacePrivate
->modemIsV92
;
7324 _SCNetworkInterfaceIsTethered(SCNetworkInterfaceRef interface
)
7326 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7328 return (interfacePrivate
->sort_order
== kSortTethered
);
7333 _SCNetworkInterfaceIsThunderbolt(SCNetworkInterfaceRef interface
)
7335 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7336 CFStringRef interfaceType
;
7338 if (!isA_SCNetworkInterface(interface
)) {
7342 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
7343 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeBridge
)) {
7348 members
= SCBridgeInterfaceGetMemberInterfaces(interface
);
7349 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
7351 // if an empty bridge
7355 for (i
= 0; i
< n
; i
++) {
7356 SCNetworkInterfaceRef member
;
7357 SCNetworkInterfacePrivateRef memberPrivate
;
7359 member
= CFArrayGetValueAtIndex(members
, i
);
7360 memberPrivate
= (SCNetworkInterfacePrivateRef
)member
;
7361 if (memberPrivate
->sort_order
!= kSortThunderbolt
) {
7366 // if Ethernet Bridge interface with only Thunderbolt [IP] members
7370 return (interfacePrivate
->sort_order
== kSortThunderbolt
);
7375 #pragma mark SCNetworkInterface [internal] SPIs
7379 SCNetworkInterfacePrivateRef
7380 __SCNetworkInterfaceCreateCopy(CFAllocatorRef allocator
,
7381 SCNetworkInterfaceRef interface
,
7382 SCPreferencesRef prefs
,
7383 CFStringRef serviceID
)
7385 SCNetworkInterfacePrivateRef oldPrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7386 SCNetworkInterfacePrivateRef newPrivate
;
7388 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
7389 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
7391 if (interface
== kSCNetworkInterfaceIPv4
) {
7392 return (SCNetworkInterfacePrivateRef
)CFRetain(interface
);
7395 newPrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, prefs
, serviceID
);
7396 newPrivate
->interface_type
= oldPrivate
->interface_type
;
7397 if (oldPrivate
->interface
!= NULL
) {
7398 newPrivate
->interface
= (SCNetworkInterfaceRef
)__SCNetworkInterfaceCreateCopy(NULL
, // allocator
7399 oldPrivate
->interface
, // interface
7400 prefs
, // [new] prefs
7401 serviceID
); // [new] serviceID
7403 if (oldPrivate
->name
!= NULL
) {
7404 newPrivate
->name
= CFRetain(oldPrivate
->name
);
7406 if (oldPrivate
->prefix
!= NULL
) {
7407 newPrivate
->prefix
= CFRetain(oldPrivate
->prefix
);
7409 if (oldPrivate
->localized_name
!= NULL
) {
7410 newPrivate
->localized_name
= CFRetain(oldPrivate
->localized_name
);
7412 newPrivate
->localized_key
= oldPrivate
->localized_key
;
7413 if (oldPrivate
->localized_arg1
!= NULL
) {
7414 newPrivate
->localized_arg1
= CFRetain(oldPrivate
->localized_arg1
);
7416 if (oldPrivate
->localized_arg2
!= NULL
) {
7417 newPrivate
->localized_arg2
= CFRetain(oldPrivate
->localized_arg2
);
7419 if (oldPrivate
->unsaved
!= NULL
) {
7420 newPrivate
->unsaved
= CFDictionaryCreateMutableCopy(NULL
, 0, oldPrivate
->unsaved
);
7422 if (oldPrivate
->entity_device
!= NULL
) {
7423 newPrivate
->entity_device
= CFRetain(oldPrivate
->entity_device
);
7425 if (oldPrivate
->entity_device_unique
!= NULL
) {
7426 newPrivate
->entity_device_unique
= CFRetain(oldPrivate
->entity_device_unique
);
7428 newPrivate
->entity_type
= oldPrivate
->entity_type
;
7429 newPrivate
->entity_subtype
= oldPrivate
->entity_subtype
;
7430 if (oldPrivate
->supported_interface_types
!= NULL
) {
7431 newPrivate
->supported_interface_types
= CFArrayCreateMutableCopy(NULL
, 0, oldPrivate
->supported_interface_types
);
7433 if (oldPrivate
->supported_protocol_types
!= NULL
) {
7434 newPrivate
->supported_protocol_types
= CFArrayCreateMutableCopy(NULL
, 0, oldPrivate
->supported_protocol_types
);
7436 if (oldPrivate
->address
!= NULL
) {
7437 newPrivate
->address
= CFRetain(oldPrivate
->address
);
7439 newPrivate
->builtin
= oldPrivate
->builtin
;
7440 if (oldPrivate
->configurationAction
!= NULL
) {
7441 newPrivate
->configurationAction
= CFRetain(oldPrivate
->configurationAction
);
7443 newPrivate
->hidden
= oldPrivate
->hidden
;
7444 if (oldPrivate
->location
!= NULL
) {
7445 newPrivate
->location
= CFRetain(oldPrivate
->location
);
7447 if (oldPrivate
->path
!= NULL
) {
7448 newPrivate
->path
= CFRetain(oldPrivate
->path
);
7450 newPrivate
->entryID
= oldPrivate
->entryID
;
7451 if (oldPrivate
->overrides
!= NULL
) {
7452 newPrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, oldPrivate
->overrides
);
7454 newPrivate
->modemIsV92
= oldPrivate
->modemIsV92
;
7455 if (oldPrivate
->type
!= NULL
) {
7456 newPrivate
->type
= CFRetain(oldPrivate
->type
);
7458 if (oldPrivate
->unit
!= NULL
) {
7459 newPrivate
->unit
= CFRetain(oldPrivate
->unit
);
7461 if (oldPrivate
->usb
.name
!= NULL
) {
7462 newPrivate
->usb
.name
= CFRetain(oldPrivate
->usb
.name
);
7464 if (oldPrivate
->usb
.vid
!= NULL
) {
7465 newPrivate
->usb
.vid
= CFRetain(oldPrivate
->usb
.vid
);
7467 if (oldPrivate
->usb
.pid
!= NULL
) {
7468 newPrivate
->usb
.pid
= CFRetain(oldPrivate
->usb
.pid
);
7470 newPrivate
->sort_order
= oldPrivate
->sort_order
;
7472 newPrivate
->supportsBond
= oldPrivate
->supportsBond
;
7473 if (oldPrivate
->bond
.interfaces
!= NULL
) {
7474 newPrivate
->bond
.interfaces
= CFRetain(oldPrivate
->bond
.interfaces
);
7476 if (oldPrivate
->bond
.mode
!= NULL
) {
7477 newPrivate
->bond
.mode
= CFRetain(oldPrivate
->bond
.mode
);
7479 if (oldPrivate
->bond
.options
!= NULL
) {
7480 newPrivate
->bond
.options
= CFRetain(oldPrivate
->bond
.options
);
7483 newPrivate
->supportsBridge
= oldPrivate
->supportsBridge
;
7484 if (oldPrivate
->bridge
.interfaces
!= NULL
) {
7485 newPrivate
->bridge
.interfaces
= CFRetain(oldPrivate
->bridge
.interfaces
);
7487 if (oldPrivate
->bridge
.options
!= NULL
) {
7488 newPrivate
->bridge
.options
= CFRetain(oldPrivate
->bridge
.options
);
7491 newPrivate
->supportsVLAN
= oldPrivate
->supportsVLAN
;
7492 if (oldPrivate
->vlan
.interface
!= NULL
) {
7493 newPrivate
->vlan
.interface
= CFRetain(oldPrivate
->vlan
.interface
);
7495 if (oldPrivate
->vlan
.tag
!= NULL
) {
7496 newPrivate
->vlan
.tag
= CFRetain(oldPrivate
->vlan
.tag
);
7498 if (oldPrivate
->vlan
.options
!= NULL
) {
7499 newPrivate
->vlan
.options
= CFRetain(oldPrivate
->vlan
.options
);
7508 __SCNetworkInterfaceCopyDeepConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
)
7510 CFMutableArrayRef configs
;
7512 configs
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
7514 while (interface
!= NULL
) {
7515 CFStringRef defaultType
;
7516 CFMutableDictionaryRef interfaceConfiguration
;
7518 interfaceConfiguration
= CFDictionaryCreateMutable(NULL
,
7520 &kCFTypeDictionaryKeyCallBacks
,
7521 &kCFTypeDictionaryValueCallBacks
);
7523 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
7524 if (defaultType
!= NULL
) {
7525 CFDictionaryRef config
;
7526 CFArrayRef extendedTypes
;
7529 config
= __SCNetworkInterfaceGetConfiguration(interface
, defaultType
);
7531 config
= __SCNetworkInterfaceGetDefaultConfiguration(set
, interface
);
7533 if (config
== NULL
) {
7534 config
= (CFDictionaryRef
)kCFNull
;
7536 CFDictionarySetValue(interfaceConfiguration
, defaultType
, config
);
7538 extendedTypes
= extendedConfigurationTypes(interface
);
7539 if (extendedTypes
!= NULL
) {
7543 n
= CFArrayGetCount(extendedTypes
);
7544 for (i
= 0; i
< n
; i
++) {
7545 CFStringRef extendedType
;
7547 extendedType
= CFArrayGetValueAtIndex(extendedTypes
, i
);
7548 config
= __SCNetworkInterfaceGetConfiguration(interface
, extendedType
);
7549 if (config
== NULL
) {
7550 config
= (CFDictionaryRef
)kCFNull
;
7552 CFDictionarySetValue(interfaceConfiguration
, extendedType
, config
);
7555 CFRelease(extendedTypes
);
7559 CFArrayAppendValue(configs
, interfaceConfiguration
);
7560 CFRelease(interfaceConfiguration
);
7562 interface
= SCNetworkInterfaceGetInterface(interface
);
7569 __private_extern__ Boolean
7570 __SCNetworkInterfaceIsMember(SCPreferencesRef prefs
, SCNetworkInterfaceRef interface
)
7572 CFArrayRef interfaces
;
7573 Boolean match
= FALSE
;
7574 CFMutableSetRef members
;
7576 members
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
7578 #if !TARGET_OS_IPHONE
7579 // add Bond [member] interfaces
7580 interfaces
= SCBondInterfaceCopyAll(prefs
);
7581 if (interfaces
!= NULL
) {
7582 __SCBondInterfaceListCollectMembers(interfaces
, members
);
7583 CFRelease(interfaces
);
7585 #endif // !TARGET_OS_IPHONE
7587 // add Bridge [member] interfaces
7588 interfaces
= SCBridgeInterfaceCopyAll(prefs
);
7589 if (interfaces
!= NULL
) {
7590 __SCBridgeInterfaceListCollectMembers(interfaces
, members
);
7591 CFRelease(interfaces
);
7594 if (CFSetGetCount(members
) == 0) {
7598 while (interface
!= NULL
) {
7599 match
= CFSetContainsValue(members
, interface
);
7601 // if the interface is a member of an
7602 // Ethernet Bond or Bridge
7606 interface
= SCNetworkInterfaceGetInterface(interface
);
7618 __SCNetworkInterfaceSetDeepConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
, CFArrayRef configs
)
7622 for (i
= 0; interface
!= NULL
; i
++) {
7623 CFStringRef defaultType
;
7624 CFDictionaryRef interfaceConfiguration
;
7626 interfaceConfiguration
= (configs
!= NULL
) ? CFArrayGetValueAtIndex(configs
, i
) : NULL
;
7628 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
7629 if (defaultType
!= NULL
) {
7630 CFDictionaryRef config
;
7631 CFArrayRef extendedTypes
;
7633 config
= (interfaceConfiguration
!= NULL
) ? CFDictionaryGetValue(interfaceConfiguration
, defaultType
)
7635 if (config
== (CFDictionaryRef
)kCFNull
) {
7639 // if service is not associated with the set
7640 if (!__SCNetworkInterfaceSetConfiguration(interface
, defaultType
, config
, TRUE
)) {
7641 SC_log(LOG_INFO
, "__SCNetworkInterfaceSetConfiguration() failed, interface=%@, type=%@",
7646 // apply default configuration to this set
7647 if (!__SCNetworkInterfaceSetDefaultConfiguration(set
, interface
, defaultType
, config
, TRUE
)) {
7648 SC_log(LOG_INFO
, "__SCNetworkInterfaceSetDefaultConfiguration() failed, interface=%@, type=%@",
7654 extendedTypes
= extendedConfigurationTypes(interface
);
7655 if (extendedTypes
!= NULL
) {
7659 n
= CFArrayGetCount(extendedTypes
);
7660 for (j
= 0; j
< n
; j
++) {
7661 CFStringRef extendedType
;
7663 extendedType
= CFArrayGetValueAtIndex(extendedTypes
, j
);
7664 config
= (interfaceConfiguration
!= NULL
) ? CFDictionaryGetValue(interfaceConfiguration
, extendedType
)
7666 if (config
== (CFDictionaryRef
)kCFNull
) {
7669 if (!__SCNetworkInterfaceSetConfiguration(interface
, extendedType
, config
, TRUE
)) {
7670 SC_log(LOG_INFO
, "__SCNetworkInterfaceSetConfiguration() failed, interface=%@, type=%@",
7676 CFRelease(extendedTypes
);
7680 interface
= SCNetworkInterfaceGetInterface(interface
);
7687 SCNetworkInterfaceRef
7688 _SCNetworkInterfaceCopyActive(SCDynamicStoreRef store
, CFStringRef bsdName
)
7690 SCNetworkInterfaceRef interface
;
7692 interface
= _SCNetworkInterfaceCreateWithBSDName(NULL
, bsdName
, kIncludeAllVirtualInterfaces
);
7693 if (interface
== NULL
) {
7697 if (store
!= NULL
) {
7698 SCNetworkInterfacePrivateRef interfacePrivate
=
7699 (SCNetworkInterfacePrivateRef
)interface
;
7702 interfacePrivate
->store
= store
;
7709 #if !TARGET_IPHONE_SIMULATOR
7710 SCNetworkServicePrimaryRank
7711 SCNetworkInterfaceGetPrimaryRank(SCNetworkInterfaceRef interface
)
7713 IPMonitorControlRef control
;
7714 SCNetworkInterfacePrivateRef interfacePrivate
=
7715 (SCNetworkInterfacePrivateRef
)interface
;
7716 SCNetworkServicePrimaryRank rank
= kSCNetworkServicePrimaryRankDefault
;
7718 control
= interfacePrivate
->IPMonitorControl
;
7719 if (control
!= NULL
) {
7722 ifName
= SCNetworkInterfaceGetBSDName(interface
);
7723 if (ifName
!= NULL
) {
7724 rank
= IPMonitorControlGetInterfacePrimaryRank(control
,
7728 _SCErrorSet(kSCStatusInvalidArgument
);
7735 SCNetworkInterfaceSetPrimaryRank(SCNetworkInterfaceRef interface
,
7736 SCNetworkServicePrimaryRank newRank
)
7738 IPMonitorControlRef control
;
7739 SCNetworkInterfacePrivateRef interfacePrivate
=
7740 (SCNetworkInterfacePrivateRef
)interface
;
7743 ifName
= SCNetworkInterfaceGetBSDName(interface
);
7744 if (ifName
== NULL
) {
7745 _SCErrorSet(kSCStatusInvalidArgument
);
7748 control
= interfacePrivate
->IPMonitorControl
;
7749 if (control
== NULL
) {
7750 control
= IPMonitorControlCreate();
7751 if (control
== NULL
) {
7752 _SCErrorSet(kSCStatusFailed
);
7755 interfacePrivate
->IPMonitorControl
= control
;
7757 return IPMonitorControlSetInterfacePrimaryRank(control
,
7763 findPerInterfaceConfig(SCNetworkInterfaceRef interface
)
7765 CFIndex interfaceIndex
;
7766 SCNetworkInterfacePrivateRef interfacePrivate
7767 = (SCNetworkInterfacePrivateRef
)interface
;
7769 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
7770 if (interfaceIndex
== kCFNotFound
7771 || !configurations
[interfaceIndex
].per_interface_config
) {
7772 return (kCFNotFound
);
7774 return (interfaceIndex
);
7778 SCNetworkInterfaceGetDisableUntilNeeded(SCNetworkInterfaceRef interface
)
7780 Boolean disable_until_needed
= FALSE
;
7781 CFNumberRef disable_prop
= NULL
;
7782 CFIndex interfaceIndex
;
7783 SCNetworkInterfacePrivateRef interfacePrivate
7784 = (SCNetworkInterfacePrivateRef
)interface
;
7785 CFArrayRef path_list
;
7787 if (interfacePrivate
->prefs
== NULL
) {
7788 _SCErrorSet(kSCStatusInvalidArgument
);
7791 interfaceIndex
= findPerInterfaceConfig(interface
);
7792 if (interfaceIndex
== kCFNotFound
) {
7793 _SCErrorSet(kSCStatusInvalidArgument
);
7796 path_list
= copyPerInterfaceConfigurationPaths(interfacePrivate
, NULL
);
7797 if (path_list
!= NULL
) {
7798 CFDictionaryRef config
;
7799 CFStringRef path
= CFArrayGetValueAtIndex(path_list
, 0);
7801 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
7802 CFRelease(path_list
);
7803 if (config
!= NULL
) {
7806 disable_prop
= CFDictionaryGetValue(config
, kSCPropDisableUntilNeeded
);
7807 disable_prop
= isA_CFNumber(disable_prop
);
7808 if (disable_prop
!= NULL
) {
7809 if (CFNumberGetValue(disable_prop
, kCFNumberIntType
, &disable
)) {
7810 disable_until_needed
= (disable
!= 0) ? TRUE
: FALSE
;
7813 /* invalid property, ignore it */
7814 disable_prop
= NULL
;
7819 if (disable_prop
== NULL
) {
7820 disable_until_needed
7821 = _SCNetworkInterfaceIsTethered(interface
);
7823 _SCErrorSet(kSCStatusOK
);
7824 return (disable_until_needed
);
7828 SCNetworkInterfaceSetDisableUntilNeeded(SCNetworkInterfaceRef interface
, Boolean disable
)
7832 CFIndex interfaceIndex
;
7833 SCNetworkInterfacePrivateRef interfacePrivate
7834 = (SCNetworkInterfacePrivateRef
)interface
;
7836 CFArrayRef path_list
;
7838 if (interfacePrivate
->prefs
== NULL
) {
7839 _SCErrorSet(kSCStatusInvalidArgument
);
7842 interfaceIndex
= findPerInterfaceConfig(interface
);
7843 if (interfaceIndex
== kCFNotFound
) {
7844 _SCErrorSet(kSCStatusInvalidArgument
);
7847 path_list
= copyPerInterfaceConfigurationPaths(interfacePrivate
, NULL
);
7848 if (path_list
== NULL
) {
7849 _SCErrorSet(kSCStatusInvalidArgument
);
7852 count
= CFArrayGetCount(path_list
);
7853 for (i
= 0; i
< count
; i
++) {
7854 CFDictionaryRef config
;
7855 CFNumberRef disable_prop
;
7856 CFMutableDictionaryRef new_config
;
7857 CFStringRef path
= CFArrayGetValueAtIndex(path_list
, i
);
7860 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
7861 if (config
!= NULL
) {
7863 = CFDictionaryCreateMutableCopy(NULL
, 0, config
);
7867 = CFDictionaryCreateMutable(NULL
, 0,
7868 &kCFTypeDictionaryKeyCallBacks
,
7869 &kCFTypeDictionaryValueCallBacks
);
7871 intval
= disable
? 1 : 0;
7872 disable_prop
= CFNumberCreate(NULL
, kCFNumberIntType
, &intval
);
7873 CFDictionarySetValue(new_config
, kSCPropDisableUntilNeeded
,
7875 CFRelease(disable_prop
);
7876 ok
= __setPrefsConfiguration(interfacePrivate
->prefs
, path
, new_config
, FALSE
);
7877 CFRelease(new_config
);
7882 CFRelease(path_list
);
7886 #else // !TARGET_IPHONE_SIMULATOR
7888 SCNetworkServicePrimaryRank
7889 SCNetworkInterfaceGetPrimaryRank(SCNetworkInterfaceRef interface
)
7891 return (kSCNetworkServicePrimaryRankDefault
);
7895 SCNetworkInterfaceSetPrimaryRank(SCNetworkInterfaceRef interface
,
7896 SCNetworkServicePrimaryRank newRank
)
7898 _SCErrorSet(kSCStatusInvalidArgument
);
7904 SCNetworkInterfaceGetDisableUntilNeeded(SCNetworkInterfaceRef interface
)
7910 SCNetworkInterfaceSetDisableUntilNeeded(SCNetworkInterfaceRef interface
, Boolean disable
)
7912 _SCErrorSet(kSCStatusInvalidArgument
);
7916 #endif // !TARGET_IPHONE_SIMULATOR
7920 CFArrayRef
// SCNetworkInterfaceRef
7921 __SCNetworkInterfaceCopyStoredWithPreferences (SCPreferencesRef ni_prefs
)
7923 CFMutableArrayRef interfaceList
= NULL
;
7925 SCNetworkInterfaceRef interfaceNamer
= NULL
;
7926 CFStringRef defaultNetworkInterfacePath
= NULL
;
7928 /* initialize runtime */
7929 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
7931 if (ni_prefs
== NULL
) {
7932 defaultNetworkInterfacePath
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@/%@"), PREFS_DEFAULT_DIR
, NETWORK_INTERFACES_PREFS
);
7933 ni_prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath
);
7936 if_list
= SCPreferencesGetValue(ni_prefs
, INTERFACES
);
7938 if (isA_CFArray(if_list
) != NULL
) {
7940 CFIndex n
= CFArrayGetCount(if_list
);
7942 interfaceList
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
7943 for (i
= 0; i
< n
; i
++) {
7944 CFDictionaryRef dict
;
7946 dict
= CFArrayGetValueAtIndex(if_list
, i
);
7947 if (isA_CFDictionary(dict
) != NULL
) {
7948 interfaceNamer
= __SCNetworkInterfaceCreateWithStorageEntity(NULL
, dict
, ni_prefs
);
7950 if (interfaceNamer
!= NULL
) {
7951 CFArrayAppendValue(interfaceList
, interfaceNamer
);
7952 CFRelease(interfaceNamer
);
7958 if (defaultNetworkInterfacePath
!= NULL
) {
7959 CFRelease(defaultNetworkInterfacePath
);
7960 // prefs were created in the function, and hence need to be released
7961 CFRelease(ni_prefs
);
7963 return interfaceList
;
7969 __SCNetworkInterfaceSaveStoredWithPreferences(SCPreferencesRef prefs
, CFArrayRef interfacesToSave
)
7971 CFStringRef defaultNetworkInterfacePath
= NULL
;
7972 Boolean success
= FALSE
;
7974 if (prefs
== NULL
) { // TODO: Get the default preferences on the system
7975 defaultNetworkInterfacePath
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@%@"), PREFS_DEFAULT_DIR
, NETWORK_INTERFACES_PREFS
);
7976 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath
);
7979 if (isA_CFArray(interfacesToSave
) == NULL
) {
7980 SC_log(LOG_INFO
, "No interfaces to save");
7983 SCPreferencesSetValue(prefs
, INTERFACES
, interfacesToSave
);
7986 if (defaultNetworkInterfacePath
!= NULL
) {
7987 CFRelease(defaultNetworkInterfacePath
);
7988 // prefs were created in the function, and hence need to be released
7996 SCNetworkInterfaceRef
7997 __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(CFAllocatorRef allocator
, SCPreferencesRef ni_prefs
, CFStringRef bsdName
)
8000 SCNetworkInterfaceRef interface
= NULL
;
8001 CFStringRef defaultNetworkInterfacePath
;
8003 /* initialize runtime */
8004 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
8006 if (ni_prefs
== NULL
) {
8007 defaultNetworkInterfacePath
= CFStringCreateWithFormat(allocator
, NULL
, CFSTR("%@/%@"), PREFS_DEFAULT_DIR
, NETWORK_INTERFACES_PREFS
);
8008 ni_prefs
= SCPreferencesCreate(allocator
, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath
);
8009 CFRelease(defaultNetworkInterfacePath
);
8015 if_list
= SCPreferencesGetValue(ni_prefs
, INTERFACES
);
8017 if (isA_CFArray(if_list
) != NULL
) {
8019 CFIndex count
= CFArrayGetCount(if_list
);
8021 for (idx
= 0; idx
< count
; idx
++) {
8022 CFDictionaryRef dict
;
8023 CFStringRef tmp_bsdName
;
8025 dict
= CFArrayGetValueAtIndex(if_list
, idx
);
8026 if (isA_CFDictionary(dict
) == NULL
) {
8030 tmp_bsdName
= CFDictionaryGetValue(dict
, CFSTR(kSCNetworkInterfaceBSDName
));
8031 if (tmp_bsdName
== NULL
) {
8034 if (CFEqual(bsdName
, tmp_bsdName
) == TRUE
) {
8035 interface
= __SCNetworkInterfaceCreateWithStorageEntity(allocator
, dict
, ni_prefs
);
8041 CFRelease(ni_prefs
);
8047 __SCNetworkInterfaceCreateMappingUsingBSDName(CFArrayRef interfaces
)
8049 CFMutableDictionaryRef mappingBSDToInterface
= NULL
;
8050 CFStringRef bsdName
= NULL
;
8051 SCNetworkInterfaceRef interface
= NULL
;
8054 count
= CFArrayGetCount(interfaces
);
8056 SC_log(LOG_INFO
, "No interfaces");
8059 mappingBSDToInterface
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
8061 for (CFIndex idx
= 0; idx
< count
; idx
++) {
8062 interface
= (SCNetworkInterfaceRef
) CFArrayGetValueAtIndex(interfaces
, idx
);
8064 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
8065 if (isA_CFString(bsdName
) == NULL
) {
8066 SC_log(LOG_INFO
, "No BSD name");
8069 CFDictionaryAddValue(mappingBSDToInterface
, bsdName
, interface
);
8071 if (CFDictionaryGetCount(mappingBSDToInterface
) == 0) {
8072 CFRelease(mappingBSDToInterface
);
8073 mappingBSDToInterface
= NULL
;
8074 SC_log(LOG_INFO
, "No mappings");
8077 return mappingBSDToInterface
;