2 * Copyright (c) 2004-2014 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/USB.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/route.h>
89 #include <sys/ioctl.h>
90 #include <sys/param.h>
91 #include <sys/types.h>
92 #include <sys/socket.h>
94 #include <sys/sysctl.h>
96 #include <NSSystemDirectories.h>
99 static CFStringRef
copy_interface_string (CFBundleRef bundle
, CFStringRef key
, Boolean localized
);
100 static CFStringRef
__SCNetworkInterfaceCopyFormattingDescription (CFTypeRef cf
, CFDictionaryRef formatOptions
);
101 static void __SCNetworkInterfaceDeallocate (CFTypeRef cf
);
102 static Boolean
__SCNetworkInterfaceEqual (CFTypeRef cf1
, CFTypeRef cf2
);
103 static CFHashCode
__SCNetworkInterfaceHash (CFTypeRef cf
);
122 kSortBluetoothPAN_GN
,
123 kSortBluetoothPAN_NAP
,
133 const CFStringRef kSCNetworkInterfaceType6to4
= CFSTR("6to4");
134 const CFStringRef kSCNetworkInterfaceTypeBluetooth
= CFSTR("Bluetooth");
135 const CFStringRef kSCNetworkInterfaceTypeBond
= CFSTR("Bond");
136 const CFStringRef kSCNetworkInterfaceTypeBridge
= CFSTR("Bridge");
137 const CFStringRef kSCNetworkInterfaceTypeEthernet
= CFSTR("Ethernet");
138 const CFStringRef kSCNetworkInterfaceTypeFireWire
= CFSTR("FireWire");
139 const CFStringRef kSCNetworkInterfaceTypeIEEE80211
= CFSTR("IEEE80211"); // IEEE 802.11, AirPort
140 const CFStringRef kSCNetworkInterfaceTypeIPSec
= CFSTR("IPSec");
141 const CFStringRef kSCNetworkInterfaceTypeIrDA
= CFSTR("IrDA");
142 const CFStringRef kSCNetworkInterfaceTypeL2TP
= CFSTR("L2TP");
143 const CFStringRef kSCNetworkInterfaceTypeLoopback
= CFSTR("Loopback");
144 const CFStringRef kSCNetworkInterfaceTypeModem
= CFSTR("Modem");
145 const CFStringRef kSCNetworkInterfaceTypePPP
= CFSTR("PPP");
146 const CFStringRef kSCNetworkInterfaceTypePPTP
= CFSTR("PPTP");
147 const CFStringRef kSCNetworkInterfaceTypeSerial
= CFSTR("Serial");
148 const CFStringRef kSCNetworkInterfaceTypeVLAN
= CFSTR("VLAN");
149 const CFStringRef kSCNetworkInterfaceTypeVPN
= CFSTR("VPN");
150 const CFStringRef kSCNetworkInterfaceTypeWWAN
= CFSTR("WWAN");
152 const CFStringRef kSCNetworkInterfaceTypeIPv4
= CFSTR("IPv4");
154 static SCNetworkInterfacePrivate __kSCNetworkInterfaceIPv4
= {
155 INIT_CFRUNTIME_BASE(), // cfBase
156 NULL
, // interface type
159 NULL
, // localized name
160 NULL
, // localization key
161 NULL
, // localization arg1
162 NULL
, // localization arg2
163 NULL
, // [layered] interface
168 NULL
, // entity_device
169 NULL
, // entity_device_unique
171 NULL
, // entity_subtype
172 NULL
, // supported_interface_types
173 NULL
, // supported_protocol_types
175 NULL
, // addressString
177 NULL
, // configurationAction
187 { NULL
, 0, 0 }, // usb { name, vid, pid }
188 kSortUnknown
, // sort_order
189 FALSE
, // supportsBond
190 { NULL
, NULL
, NULL
}, // bond { interfaces, mode, options }
191 FALSE
, // supportsBridge
192 { NULL
, NULL
}, // bridge { interfaces, options }
193 FALSE
, // supportsVLAN
194 { NULL
, NULL
, NULL
}, // vlan { interface, tag, options }
195 #if !TARGET_IPHONE_SIMULATOR
196 NULL
, // IPMonitorControl
197 #endif // !TARGET_IPHONE_SIMULATOR
200 const SCNetworkInterfaceRef kSCNetworkInterfaceIPv4
= (SCNetworkInterfaceRef
)&__kSCNetworkInterfaceIPv4
;
202 static SCNetworkInterfacePrivate __kSCNetworkInterfaceLoopback
= {
203 INIT_CFRUNTIME_BASE(), // cfBase
204 NULL
, // interface type
207 NULL
, // localized name
208 NULL
, // localization key
209 NULL
, // localization arg1
210 NULL
, // localization arg2
211 NULL
, // [layered] interface
216 NULL
, // entity_device
217 NULL
, // entity_device_unique
219 NULL
, // entity_subtype
220 NULL
, // supported_interface_types
221 NULL
, // supported_protocol_types
223 NULL
, // addressString
225 NULL
, // configurationAction
235 { NULL
, 0, 0 }, // usb { name, vid, pid }
236 kSortUnknown
, // sort_order
237 FALSE
, // supportsBond
238 { NULL
, NULL
, NULL
}, // bond { interfaces, mode, options }
239 FALSE
, // supportsBridge
240 { NULL
, NULL
}, // bridge { interfaces, options }
241 FALSE
, // supportsVLAN
242 { NULL
, NULL
, NULL
}, // vlan { interface, tag, options }
243 #if !TARGET_IPHONE_SIMULATOR
244 NULL
, // IPMonitorControl
245 #endif // !TARGET_IPHONE_SIMULATOR
248 const SCNetworkInterfaceRef kSCNetworkInterfaceLoopback
= (SCNetworkInterfaceRef
)&__kSCNetworkInterfaceLoopback
;
250 static CFMutableSetRef vendor_interface_types
= NULL
;
253 #pragma mark SCNetworkInterface configuration details
262 #define doOverIP do6to4|doL2TP|doPPTP|doIPSec
267 #define doProxies 1<<4
268 #if !TARGET_OS_IPHONE
270 #else // !TARGET_OS_IPHONE
272 #endif // !TARGET_OS_IPHONE
274 static const struct {
275 const CFStringRef
*interface_type
;
276 const CFStringRef
*entity_hardware
;
277 Boolean per_interface_config
;
278 uint32_t supported_interfaces
;
279 const CFStringRef
*ppp_subtype
;
280 uint32_t supported_protocols
;
281 } configurations
[] = {
282 // interface type entity_hardware if config? interface types PPP sub-type interface protocols
283 // ===================================== ==================== ========== =============== ======================================= =========================================
284 { &kSCNetworkInterfaceType6to4
, &kSCEntNet6to4
, FALSE
, doNone
, NULL
, doIPv6
},
285 { &kSCNetworkInterfaceTypeBluetooth
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
286 { &kSCNetworkInterfaceTypeBond
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
287 { &kSCNetworkInterfaceTypeBridge
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
288 { &kSCNetworkInterfaceTypeEthernet
, &kSCEntNetEthernet
, TRUE
, doPPP
, &kSCValNetInterfaceSubTypePPPoE
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
289 { &kSCNetworkInterfaceTypeFireWire
, &kSCEntNetFireWire
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
290 { &kSCNetworkInterfaceTypeIEEE80211
, &kSCEntNetAirPort
, TRUE
, doPPP
, &kSCValNetInterfaceSubTypePPPoE
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
291 { &kSCNetworkInterfaceTypeIPSec
, &kSCEntNetIPSec
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
292 { &kSCNetworkInterfaceTypeIrDA
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
293 { &kSCNetworkInterfaceTypeL2TP
, NULL
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypeL2TP
, doNone
},
294 { &kSCNetworkInterfaceTypeModem
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
295 { &kSCNetworkInterfaceTypePPP
, &kSCEntNetPPP
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
296 { &kSCNetworkInterfaceTypePPTP
, NULL
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPTP
, doNone
},
297 { &kSCNetworkInterfaceTypeSerial
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
298 { &kSCNetworkInterfaceTypeVLAN
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
299 { &kSCNetworkInterfaceTypeVPN
, &kSCEntNetVPN
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
300 { &kSCNetworkInterfaceTypeWWAN
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
301 // ===================================== =================== ========== =============== ======================================= =========================================
302 { &kSCNetworkInterfaceTypeLoopback
, NULL
, TRUE
, doNone
, NULL
, doIPv4
|doIPv6
},
303 // ===================================== =================== ========== =============== ======================================= =========================================
304 { &kSCNetworkInterfaceTypeIPv4
, NULL
, FALSE
, doOverIP
, NULL
, doNone
}
308 #define kSCNetworkInterfaceActive "Active"
309 #define kSCNetworkInterfaceInfo "SCNetworkInterfaceInfo"
310 #define kSCNetworkInterfaceType "SCNetworkInterfaceType"
311 #define kSCNetworkInterfaceBSDName kIOBSDNameKey
312 #define kSCNetworkInterfaceIOBuiltin kIOBuiltin
313 #define kSCNetworkInterfaceIOInterfaceNamePrefix kIOInterfaceNamePrefix
314 #define kSCNetworkInterfaceIOInterfaceType kIOInterfaceType
315 #define kSCNetworkInterfaceIOInterfaceUnit kIOInterfaceUnit
316 #define kSCNetworkInterfaceIOMACAddress kIOMACAddress
317 #define kSCNetworkInterfaceIOPathMatch kIOPathMatchKey
320 #define NETWORKINTERFACE_LOCALIZATIONS CFSTR("NetworkInterface")
321 static CFBundleRef bundle
= NULL
;
324 static CFTypeID __kSCNetworkInterfaceTypeID
= _kCFRuntimeNotATypeID
;
327 static const CFRuntimeClass __SCNetworkInterfaceClass
= {
329 "SCNetworkInterface", // className
332 __SCNetworkInterfaceDeallocate
, // dealloc
333 __SCNetworkInterfaceEqual
, // equal
334 __SCNetworkInterfaceHash
, // hash
335 __SCNetworkInterfaceCopyFormattingDescription
, // copyFormattingDesc
336 NULL
// copyDebugDesc
340 static pthread_once_t initialized
= PTHREAD_ONCE_INIT
;
341 static pthread_once_t iokit_quiet
= PTHREAD_ONCE_INIT
;
344 static mach_port_t masterPort
= MACH_PORT_NULL
;
348 __SCNetworkInterfaceCopyFormattingDescription(CFTypeRef cf
, CFDictionaryRef formatOptions
)
350 CFAllocatorRef allocator
= CFGetAllocator(cf
);
351 CFMutableStringRef result
;
352 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
354 result
= CFStringCreateMutable(allocator
, 0);
355 CFStringAppendFormat(result
, NULL
, CFSTR("<SCNetworkInterface %p [%p]> {"), cf
, allocator
);
356 CFStringAppendFormat(result
, NULL
, CFSTR("type = %@"), interfacePrivate
->interface_type
);
357 CFStringAppendFormat(result
, NULL
, CFSTR(", entity_device = %@"), interfacePrivate
->entity_device
);
358 if (interfacePrivate
->entity_device_unique
!= NULL
) {
359 CFStringAppendFormat(result
, NULL
, CFSTR("+%@"), interfacePrivate
->entity_device_unique
);
361 CFStringAppendFormat(result
, NULL
, CFSTR(", entity_type = %@"), interfacePrivate
->entity_type
);
362 if (interfacePrivate
->entity_subtype
!= NULL
) {
363 CFStringAppendFormat(result
, NULL
, CFSTR(" / %@"), interfacePrivate
->entity_subtype
);
365 if (interfacePrivate
->name
!= NULL
) {
366 CFStringAppendFormat(result
, NULL
, CFSTR(", name = %@"), interfacePrivate
->name
);
368 if (interfacePrivate
->localized_name
!= NULL
) {
369 CFStringAppendFormat(result
, NULL
, CFSTR(", name(l) = %@"), interfacePrivate
->localized_name
);
371 if (interfacePrivate
->localized_key
!= NULL
) {
372 CFStringAppendFormat(result
, NULL
, CFSTR(", name(k) = \"%@\""), interfacePrivate
->localized_key
);
373 if (interfacePrivate
->localized_arg1
!= NULL
) {
374 CFStringAppendFormat(result
, NULL
, CFSTR("+\"%@\""), interfacePrivate
->localized_arg1
);
376 if (interfacePrivate
->localized_arg2
!= NULL
) {
377 CFStringAppendFormat(result
, NULL
, CFSTR("+\"%@\""), interfacePrivate
->localized_arg2
);
381 if (interfacePrivate
->address
!= NULL
) {
386 CFStringAppendFormat(result
, NULL
, CFSTR(", address = 0x"));
388 data
= CFDataGetBytePtr(interfacePrivate
->address
);
389 dataLen
= CFDataGetLength(interfacePrivate
->address
);
390 for (i
= 0; i
< dataLen
; i
++) {
391 CFStringAppendFormat(result
, NULL
, CFSTR("%02x"), data
[i
]);
394 CFStringAppendFormat(result
, NULL
, CFSTR(", builtin = %s"), interfacePrivate
->builtin
? "TRUE" : "FALSE");
395 if (interfacePrivate
->hidden
) {
396 CFStringAppendFormat(result
, NULL
, CFSTR(", hidden = TRUE"));
398 if (interfacePrivate
->modemIsV92
) {
399 CFStringAppendFormat(result
, NULL
, CFSTR(", v.92"));
401 if (interfacePrivate
->location
!= NULL
) {
402 CFStringAppendFormat(result
, NULL
, CFSTR(", location = %@"), interfacePrivate
->location
);
404 if (interfacePrivate
->path
!= NULL
) {
405 CFStringAppendFormat(result
, NULL
, CFSTR(", path = %@"), interfacePrivate
->path
);
407 if (interfacePrivate
->entryID
!= 0) {
408 CFStringAppendFormat(result
, NULL
, CFSTR(", entryID = 0x%llx"), interfacePrivate
->entryID
);
410 if (interfacePrivate
->type
!= NULL
) {
411 CFStringAppendFormat(result
, NULL
, CFSTR(", type = %@"), interfacePrivate
->type
);
413 if (interfacePrivate
->unit
!= NULL
) {
414 CFStringAppendFormat(result
, NULL
, CFSTR(", unit = %@"), interfacePrivate
->unit
);
416 if ((interfacePrivate
->usb
.vid
!= NULL
) || (interfacePrivate
->usb
.pid
!= NULL
)) {
420 if (!isA_CFNumber(interfacePrivate
->usb
.pid
) ||
421 !CFNumberGetValue(interfacePrivate
->usb
.pid
, kCFNumberIntType
, &pid
)) {
424 if (!isA_CFNumber(interfacePrivate
->usb
.vid
) ||
425 !CFNumberGetValue(interfacePrivate
->usb
.vid
, kCFNumberIntType
, &vid
)) {
429 if (interfacePrivate
->usb
.name
!= NULL
) {
430 CFStringAppendFormat(result
, NULL
, CFSTR(", USB name = %@"),
431 interfacePrivate
->usb
.name
);
434 CFStringAppendFormat(result
, NULL
, CFSTR(", USB vid/pid = 0x%0x/0x%0x"),
438 if (interfacePrivate
->configurationAction
!= NULL
) {
439 CFStringAppendFormat(result
, NULL
, CFSTR(", action = %@"), interfacePrivate
->configurationAction
);
441 if (interfacePrivate
->overrides
!= NULL
) {
442 CFStringAppendFormat(result
, formatOptions
, CFSTR(", overrides = %p"), interfacePrivate
->overrides
);
444 CFStringAppendFormat(result
, NULL
, CFSTR(", order = %d"), interfacePrivate
->sort_order
);
445 if (interfacePrivate
->prefs
!= NULL
) {
446 CFStringAppendFormat(result
, NULL
, CFSTR(", prefs = %p"), interfacePrivate
->prefs
);
448 if (interfacePrivate
->serviceID
!= NULL
) {
449 CFStringAppendFormat(result
, NULL
, CFSTR(", service = %@"), interfacePrivate
->serviceID
);
451 if (interfacePrivate
->interface
!= NULL
) {
452 CFStringAppendFormat(result
, NULL
, CFSTR(", interface = %@"), interfacePrivate
->interface
);
454 if (interfacePrivate
->unsaved
!= NULL
) {
455 CFStringAppendFormat(result
, formatOptions
, CFSTR(", unsaved = %@"), interfacePrivate
->unsaved
);
458 if (interfacePrivate
->bond
.interfaces
!= NULL
) {
462 n
= CFArrayGetCount(interfacePrivate
->bond
.interfaces
);
463 for (i
= 0; i
< n
; i
++) {
464 SCNetworkInterfaceRef member
;
466 member
= CFArrayGetValueAtIndex(interfacePrivate
->bond
.interfaces
, i
);
467 CFStringAppendFormat(result
, NULL
,
469 (i
== 0) ? ", interfaces = " : ",",
470 SCNetworkInterfaceGetBSDName(member
));
473 if (interfacePrivate
->bond
.mode
!= NULL
) {
474 CFStringAppendFormat(result
, NULL
, CFSTR(", mode = %@"), interfacePrivate
->bond
.mode
);
476 if (interfacePrivate
->bond
.options
!= NULL
) {
479 str
= _SCCopyDescription(interfacePrivate
->bond
.options
, formatOptions
);
480 CFStringAppendFormat(result
, formatOptions
, CFSTR(", options = %@"), str
);
484 if (interfacePrivate
->bridge
.interfaces
!= NULL
) {
488 n
= CFArrayGetCount(interfacePrivate
->bridge
.interfaces
);
489 for (i
= 0; i
< n
; i
++) {
490 SCNetworkInterfaceRef member
;
492 member
= CFArrayGetValueAtIndex(interfacePrivate
->bridge
.interfaces
, i
);
493 CFStringAppendFormat(result
, NULL
,
495 (i
== 0) ? ", interfaces = " : ",",
496 SCNetworkInterfaceGetBSDName(member
));
499 if (interfacePrivate
->bridge
.options
!= NULL
) {
502 str
= _SCCopyDescription(interfacePrivate
->bridge
.options
, formatOptions
);
503 CFStringAppendFormat(result
, formatOptions
, CFSTR(", options = %@"), str
);
507 if (interfacePrivate
->vlan
.interface
!= NULL
) {
508 CFStringAppendFormat(result
, NULL
,
509 CFSTR(", interface = %@"),
510 SCNetworkInterfaceGetBSDName(interfacePrivate
->vlan
.interface
));
512 if (interfacePrivate
->vlan
.tag
!= NULL
) {
513 CFStringAppendFormat(result
, NULL
, CFSTR(", tag = %@"), interfacePrivate
->vlan
.tag
);
515 if (interfacePrivate
->vlan
.options
!= NULL
) {
518 str
= _SCCopyDescription(interfacePrivate
->vlan
.options
, formatOptions
);
519 CFStringAppendFormat(result
, formatOptions
, CFSTR(", options = %@"), str
);
523 CFStringAppendFormat(result
, NULL
, CFSTR("}"));
530 __SCNetworkInterfaceDeallocate(CFTypeRef cf
)
532 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
534 /* release resources */
536 if (interfacePrivate
->name
!= NULL
)
537 CFRelease(interfacePrivate
->name
);
539 if (interfacePrivate
->localized_name
!= NULL
)
540 CFRelease(interfacePrivate
->localized_name
);
542 if (interfacePrivate
->localized_arg1
!= NULL
)
543 CFRelease(interfacePrivate
->localized_arg1
);
545 if (interfacePrivate
->localized_arg2
!= NULL
)
546 CFRelease(interfacePrivate
->localized_arg2
);
548 if (interfacePrivate
->interface
!= NULL
)
549 CFRelease(interfacePrivate
->interface
);
551 if (interfacePrivate
->prefs
!= NULL
)
552 CFRelease(interfacePrivate
->prefs
);
554 if (interfacePrivate
->store
!= NULL
)
555 CFRelease(interfacePrivate
->store
);
557 if (interfacePrivate
->serviceID
!= NULL
)
558 CFRelease(interfacePrivate
->serviceID
);
560 if (interfacePrivate
->unsaved
!= NULL
)
561 CFRelease(interfacePrivate
->unsaved
);
563 if (interfacePrivate
->entity_device
!= NULL
)
564 CFRelease(interfacePrivate
->entity_device
);
566 if (interfacePrivate
->entity_device_unique
!= NULL
)
567 CFRelease(interfacePrivate
->entity_device_unique
);
569 if (interfacePrivate
->supported_interface_types
!= NULL
)
570 CFRelease(interfacePrivate
->supported_interface_types
);
572 if (interfacePrivate
->supported_protocol_types
!= NULL
)
573 CFRelease(interfacePrivate
->supported_protocol_types
);
575 if (interfacePrivate
->address
!= NULL
)
576 CFRelease(interfacePrivate
->address
);
578 if (interfacePrivate
->addressString
!= NULL
)
579 CFRelease(interfacePrivate
->addressString
);
581 if (interfacePrivate
->configurationAction
!= NULL
)
582 CFRelease(interfacePrivate
->configurationAction
);
584 if (interfacePrivate
->location
!= NULL
)
585 CFRelease(interfacePrivate
->location
);
587 if (interfacePrivate
->path
!= NULL
)
588 CFRelease(interfacePrivate
->path
);
590 if (interfacePrivate
->overrides
!= NULL
)
591 CFRelease(interfacePrivate
->overrides
);
593 if (interfacePrivate
->prefix
!= NULL
)
594 CFRelease(interfacePrivate
->prefix
);
596 if (interfacePrivate
->type
!= NULL
)
597 CFRelease(interfacePrivate
->type
);
599 if (interfacePrivate
->unit
!= NULL
)
600 CFRelease(interfacePrivate
->unit
);
602 if (interfacePrivate
->usb
.name
!= NULL
)
603 CFRelease(interfacePrivate
->usb
.name
);
605 if (interfacePrivate
->usb
.pid
!= NULL
)
606 CFRelease(interfacePrivate
->usb
.pid
);
608 if (interfacePrivate
->usb
.vid
!= NULL
)
609 CFRelease(interfacePrivate
->usb
.vid
);
611 if (interfacePrivate
->bond
.interfaces
!= NULL
)
612 CFRelease(interfacePrivate
->bond
.interfaces
);
614 if (interfacePrivate
->bond
.mode
!= NULL
)
615 CFRelease(interfacePrivate
->bond
.mode
);
617 if (interfacePrivate
->bond
.options
!= NULL
)
618 CFRelease(interfacePrivate
->bond
.options
);
620 if (interfacePrivate
->bridge
.interfaces
!= NULL
)
621 CFRelease(interfacePrivate
->bridge
.interfaces
);
623 if (interfacePrivate
->bridge
.options
!= NULL
)
624 CFRelease(interfacePrivate
->bridge
.options
);
626 if (interfacePrivate
->vlan
.interface
!= NULL
)
627 CFRelease(interfacePrivate
->vlan
.interface
);
629 if (interfacePrivate
->vlan
.tag
!= NULL
)
630 CFRelease(interfacePrivate
->vlan
.tag
);
632 if (interfacePrivate
->vlan
.options
!= NULL
)
633 CFRelease(interfacePrivate
->vlan
.options
);
634 #if !TARGET_IPHONE_SIMULATOR
635 if (interfacePrivate
->IPMonitorControl
!= NULL
)
636 CFRelease(interfacePrivate
->IPMonitorControl
);
637 #endif // !TARGET_IPHONE_SIMULATOR
643 __SCNetworkInterfaceEqual(CFTypeRef cf1
, CFTypeRef cf2
)
645 SCNetworkInterfacePrivateRef if1
= (SCNetworkInterfacePrivateRef
)cf1
;
646 SCNetworkInterfacePrivateRef if2
= (SCNetworkInterfacePrivateRef
)cf2
;
651 if (!CFEqual(if1
->interface_type
, if2
->interface_type
)) {
652 return FALSE
; // if not the same interface type
655 if (!_SC_CFEqual(if1
->entity_device
, if2
->entity_device
)) {
656 return FALSE
; // if not the same device
659 if ((if1
->entity_device_unique
!= NULL
) && (if2
->entity_device_unique
!= NULL
)) {
660 if (!_SC_CFEqual(if1
->entity_device_unique
, if2
->entity_device_unique
)) {
661 return FALSE
; // if not the same device unique identifier
663 } else if ((if1
->entity_device_unique
!= NULL
) || (if2
->entity_device_unique
!= NULL
)) {
667 name1
= __SCNetworkInterfaceGetNonLocalizedDisplayName((SCNetworkInterfaceRef
)if1
);
668 name2
= __SCNetworkInterfaceGetNonLocalizedDisplayName((SCNetworkInterfaceRef
)if2
);
669 if ((name1
!= NULL
) && (name2
!= NULL
) && !_SC_CFEqual(name1
, name2
)) {
670 return FALSE
; // if same device but not the same display name
674 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeBond
)) {
675 if (!_SC_CFEqual(if1
->bond
.interfaces
, if2
->bond
.interfaces
)) {
676 return FALSE
; // if not the same interfaces
678 if (!_SC_CFEqual(if1
->bond
.mode
, if2
->bond
.mode
)) {
679 return FALSE
; // if not the same mode
683 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeBridge
)) {
684 if (!_SC_CFEqual(if1
->bridge
.interfaces
, if2
->bridge
.interfaces
)) {
685 return FALSE
; // if not the same interfaces
689 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeVLAN
)) {
690 if (!_SC_CFEqual(if1
->vlan
.interface
, if2
->vlan
.interface
)) {
691 return FALSE
; // if not the same physical interface
693 if (!_SC_CFEqual(if1
->vlan
.tag
, if2
->vlan
.tag
)) {
694 return FALSE
; // if not the same tag
698 if (!_SC_CFEqual(if1
->interface
, if2
->interface
)) {
699 return FALSE
; // if not the same layering
707 __SCNetworkInterfaceHash(CFTypeRef cf
)
710 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
712 if (interfacePrivate
->entity_device
!= NULL
) {
713 if (interfacePrivate
->entity_device_unique
== NULL
) {
714 hash
= CFHash(interfacePrivate
->entity_device
);
718 str
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@+%@"),
719 interfacePrivate
->entity_device
,
720 interfacePrivate
->entity_device_unique
);
731 __SCNetworkInterfaceInitialize(void)
736 __kSCNetworkInterfaceTypeID
= _CFRuntimeRegisterClass(&__SCNetworkInterfaceClass
);
738 // initialize __kSCNetworkInterfaceIPv4
739 _CFRuntimeInitStaticInstance(&__kSCNetworkInterfaceIPv4
, __kSCNetworkInterfaceTypeID
);
740 __kSCNetworkInterfaceIPv4
.interface_type
= kSCNetworkInterfaceTypeIPv4
;
741 __kSCNetworkInterfaceIPv4
.localized_key
= CFSTR("ipv4");
743 // initialize __kSCNetworkInterfaceLoopback
744 _CFRuntimeInitStaticInstance(&__kSCNetworkInterfaceLoopback
, __kSCNetworkInterfaceTypeID
);
745 __kSCNetworkInterfaceLoopback
.interface_type
= kSCNetworkInterfaceTypeLoopback
;
746 __kSCNetworkInterfaceLoopback
.localized_key
= CFSTR("loopback");
747 __kSCNetworkInterfaceLoopback
.entity_device
= CFRetain(CFSTR("lo0"));
748 __kSCNetworkInterfaceLoopback
.entity_type
= kSCValNetInterfaceTypeLoopback
;
750 // get CFBundleRef for SystemConfiguration.framework
751 bundle
= _SC_CFBundleGet();
753 // get mach port used to communication with IOKit
754 kr
= IOMasterPort(MACH_PORT_NULL
, &masterPort
);
755 if (kr
!= kIOReturnSuccess
) {
756 SCLog(TRUE
, LOG_DEBUG
,
757 CFSTR("__SCNetworkInterfaceInitialize(), could not get IOMasterPort, kr = 0x%x"),
766 SCNetworkInterfacePrivateRef
767 __SCNetworkInterfaceCreatePrivate(CFAllocatorRef allocator
,
768 SCNetworkInterfaceRef interface
,
769 SCPreferencesRef prefs
,
770 CFStringRef serviceID
)
772 SCNetworkInterfacePrivateRef interfacePrivate
;
775 /* initialize runtime */
776 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
778 /* allocate target */
779 size
= sizeof(SCNetworkInterfacePrivate
) - sizeof(CFRuntimeBase
);
780 interfacePrivate
= (SCNetworkInterfacePrivateRef
)_CFRuntimeCreateInstance(allocator
,
781 __kSCNetworkInterfaceTypeID
,
784 if (interfacePrivate
== NULL
) {
788 interfacePrivate
->interface_type
= NULL
;
789 interfacePrivate
->active
= FALSE
;
790 interfacePrivate
->name
= NULL
;
791 interfacePrivate
->localized_name
= NULL
;
792 interfacePrivate
->localized_key
= NULL
;
793 interfacePrivate
->localized_arg1
= NULL
;
794 interfacePrivate
->localized_arg2
= NULL
;
795 interfacePrivate
->interface
= (interface
!= NULL
) ? CFRetain(interface
) : NULL
;
796 interfacePrivate
->prefs
= (prefs
!= NULL
) ? CFRetain(prefs
) : NULL
;
797 interfacePrivate
->store
= NULL
;
798 interfacePrivate
->serviceID
= (serviceID
!= NULL
) ? CFRetain(serviceID
) : NULL
;
799 interfacePrivate
->unsaved
= NULL
;
800 interfacePrivate
->entity_device
= NULL
;
801 interfacePrivate
->entity_device_unique
= NULL
;
802 interfacePrivate
->entity_type
= NULL
;
803 interfacePrivate
->entity_subtype
= NULL
;
804 interfacePrivate
->supported_interface_types
= NULL
;
805 interfacePrivate
->supported_protocol_types
= NULL
;
806 interfacePrivate
->address
= NULL
;
807 interfacePrivate
->addressString
= NULL
;
808 interfacePrivate
->builtin
= FALSE
;
809 interfacePrivate
->configurationAction
= NULL
;
810 interfacePrivate
->hidden
= FALSE
;
811 interfacePrivate
->location
= NULL
;
812 interfacePrivate
->path
= NULL
;
813 interfacePrivate
->entryID
= 0;
814 interfacePrivate
->overrides
= NULL
;
815 interfacePrivate
->modemIsV92
= FALSE
;
816 interfacePrivate
->prefix
= NULL
;
817 interfacePrivate
->type
= NULL
;
818 interfacePrivate
->unit
= NULL
;
819 interfacePrivate
->usb
.name
= NULL
;
820 interfacePrivate
->usb
.vid
= NULL
;
821 interfacePrivate
->usb
.pid
= NULL
;
822 interfacePrivate
->sort_order
= kSortUnknown
;
824 interfacePrivate
->supportsBond
= FALSE
;
825 interfacePrivate
->bond
.interfaces
= NULL
;
826 interfacePrivate
->bond
.mode
= NULL
;
827 interfacePrivate
->bond
.options
= NULL
;
829 interfacePrivate
->supportsBridge
= FALSE
;
830 interfacePrivate
->bridge
.interfaces
= NULL
;
831 interfacePrivate
->bridge
.options
= NULL
;
833 interfacePrivate
->supportsVLAN
= FALSE
;
834 interfacePrivate
->vlan
.interface
= NULL
;
835 interfacePrivate
->vlan
.tag
= NULL
;
836 interfacePrivate
->vlan
.options
= NULL
;
838 return interfacePrivate
;
844 __SCNetworkInterfaceSupportsVLAN(CFStringRef bsd_if
)
848 struct if_msghdr
* ifm
;
849 char * if_name
= NULL
;
850 unsigned int if_index
;
852 Boolean vlanOK
= FALSE
;
854 // get the interface index
855 if_name
= _SC_cfstring_to_cstring(bsd_if
, NULL
, 0, kCFStringEncodingASCII
);
856 if (if_name
== NULL
) {
857 return FALSE
; // if conversion error
859 if_index
= if_nametoindex(if_name
);
861 goto done
; // if unknown interface
864 // get information for the specified interface
869 mib
[4] = NET_RT_IFLIST
;
870 mib
[5] = if_index
; /* ask for exactly one interface */
872 if (sysctl(mib
, 6, NULL
, &buf_len
, NULL
, 0) == -1) {
873 SCLog(TRUE
, LOG_ERR
, CFSTR("sysctl() size failed: %s"), strerror(errno
));
876 buf
= CFAllocatorAllocate(NULL
, buf_len
, 0);
877 if (sysctl(mib
, 6, buf
, &buf_len
, NULL
, 0) == -1) {
878 SCLog(TRUE
, LOG_ERR
, CFSTR("sysctl() failed: %s"), strerror(errno
));
882 // check the link type and hwassist flags
883 // ALIGN: buf is aligned
884 ifm
= (struct if_msghdr
*)(void *)buf
;
885 switch (ifm
->ifm_type
) {
887 #if defined(IF_HWASSIST_VLAN_TAGGING) && defined(IF_HWASSIST_VLAN_MTU)
888 struct if_data
*if_data
= &ifm
->ifm_data
;
890 if (if_data
->ifi_hwassist
& (IF_HWASSIST_VLAN_TAGGING
| IF_HWASSIST_VLAN_MTU
)) {
900 if (if_name
!= NULL
) CFAllocatorDeallocate(NULL
, if_name
);
901 if (buf
!= NULL
) CFAllocatorDeallocate(NULL
, buf
);
908 SCNetworkInterfacePrivateRef
909 _SCBondInterfaceCreatePrivate(CFAllocatorRef allocator
,
912 SCNetworkInterfacePrivateRef interfacePrivate
;
914 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
);
915 if (interfacePrivate
== NULL
) {
919 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBond
;
920 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
921 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, bond_if
);
922 interfacePrivate
->builtin
= TRUE
;
923 interfacePrivate
->supportsVLAN
= __SCNetworkInterfaceSupportsVLAN(bond_if
);
924 interfacePrivate
->sort_order
= kSortBond
;
926 interfacePrivate
->localized_key
= CFSTR("bond");
927 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
929 interfacePrivate
->bond
.interfaces
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
930 // interfacePrivate->bond.mode = NULL;
931 // interfacePrivate->bond.options = NULL;
933 return interfacePrivate
;
938 SCNetworkInterfacePrivateRef
939 _SCBridgeInterfaceCreatePrivate(CFAllocatorRef allocator
,
940 CFStringRef bridge_if
)
942 SCNetworkInterfacePrivateRef interfacePrivate
;
944 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
);
945 if (interfacePrivate
== NULL
) {
949 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBridge
;
950 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
951 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, bridge_if
);
952 interfacePrivate
->builtin
= TRUE
;
953 interfacePrivate
->supportsVLAN
= __SCNetworkInterfaceSupportsVLAN(bridge_if
);
954 interfacePrivate
->sort_order
= kSortBridge
;
956 interfacePrivate
->localized_key
= CFSTR("bridge");
957 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
959 interfacePrivate
->bridge
.interfaces
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
960 // interfacePrivate->bridge.options = NULL;
962 return interfacePrivate
;
967 SCNetworkInterfacePrivateRef
968 _SCVLANInterfaceCreatePrivate(CFAllocatorRef allocator
,
971 SCNetworkInterfacePrivateRef interfacePrivate
;
973 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
);
974 if (interfacePrivate
== NULL
) {
978 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeVLAN
;
979 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
980 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, vlan_if
);
981 interfacePrivate
->builtin
= TRUE
;
982 interfacePrivate
->sort_order
= kSortVLAN
;
984 interfacePrivate
->localized_key
= CFSTR("vlan");
985 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
987 // interfacePrivate->vlan.interface = NULL;
988 // interfacePrivate->vlan.tag = NULL;
989 // interfacePrivate->vlan.options = NULL;
991 return interfacePrivate
;
996 #pragma mark Interface ordering
999 static CF_RETURNS_RETAINED CFArrayRef
1000 split_path(CFStringRef path
)
1002 CFArrayRef components
;
1003 CFMutableStringRef nPath
;
1005 // turn '@'s into '/'s
1006 nPath
= CFStringCreateMutableCopy(NULL
, 0, path
);
1007 (void) CFStringFindAndReplace(nPath
,
1010 CFRangeMake(0, CFStringGetLength(nPath
)),
1013 // split path into components to be compared
1014 components
= CFStringCreateArrayBySeparatingStrings(NULL
, nPath
, CFSTR("/"));
1022 _SCNetworkInterfaceCompare(const void *val1
, const void *val2
, void *context
)
1024 SCNetworkInterfacePrivateRef dev1
= (SCNetworkInterfacePrivateRef
)val1
;
1025 SCNetworkInterfacePrivateRef dev2
= (SCNetworkInterfacePrivateRef
)val2
;
1026 CFComparisonResult res
= kCFCompareEqualTo
;
1028 /* sort by interface type */
1029 if (dev1
->sort_order
!= dev2
->sort_order
) {
1030 if (dev1
->sort_order
< dev2
->sort_order
) {
1031 res
= kCFCompareLessThan
;
1033 res
= kCFCompareGreaterThan
;
1038 /* built-in interfaces sort first */
1039 if (dev1
->builtin
!= dev2
->builtin
) {
1040 if (dev1
->builtin
) {
1041 res
= kCFCompareLessThan
;
1043 res
= kCFCompareGreaterThan
;
1048 /* ... and then, sort built-in interfaces by "location" */
1049 if (dev1
->builtin
) {
1050 if (dev1
->location
!= dev2
->location
) {
1051 if (isA_CFString(dev1
->location
)) {
1052 if (isA_CFString(dev2
->location
)) {
1053 res
= CFStringCompare(dev1
->location
, dev2
->location
, 0);
1055 res
= kCFCompareLessThan
;
1058 res
= kCFCompareGreaterThan
;
1061 if (res
!= kCFCompareEqualTo
) {
1067 /* ... and, then sort by IOPathMatch */
1068 if ((dev1
->path
!= NULL
) && (dev2
->path
!= NULL
)) {
1069 CFArrayRef elements1
;
1070 CFArrayRef elements2
;
1076 elements1
= split_path(dev1
->path
);
1077 n1
= CFArrayGetCount(elements1
);
1079 elements2
= split_path(dev2
->path
);
1080 n2
= CFArrayGetCount(elements2
);
1082 n
= (n1
<= n2
) ? n1
: n2
;
1083 for (i
= 0; i
< n
; i
++) {
1092 e1
= CFArrayGetValueAtIndex(elements1
, i
);
1093 e2
= CFArrayGetValueAtIndex(elements2
, i
);
1095 str
= _SC_cfstring_to_cstring(e1
, NULL
, 0, kCFStringEncodingUTF8
);
1097 q1
= strtoq(str
, &end
, 16);
1098 isNum
= ((*str
!= '\0') && (*end
== '\0') && (errno
== 0));
1099 CFAllocatorDeallocate(NULL
, str
);
1102 // if e1 is a valid numeric string
1103 str
= _SC_cfstring_to_cstring(e2
, NULL
, 0, kCFStringEncodingUTF8
);
1105 q2
= strtoq(str
, &end
, 16);
1106 isNum
= ((*str
!= '\0') && (*end
== '\0') && (errno
== 0));
1107 CFAllocatorDeallocate(NULL
, str
);
1110 // if e2 is also a valid numeric string
1113 res
= kCFCompareEqualTo
;
1115 } else if (q1
< q2
) {
1116 res
= kCFCompareLessThan
;
1118 res
= kCFCompareGreaterThan
;
1124 res
= CFStringCompare(e1
, e2
, 0);
1125 if (res
!= kCFCompareEqualTo
) {
1130 if (res
== kCFCompareEqualTo
) {
1132 res
= kCFCompareLessThan
;
1133 } else if (n1
< n2
) {
1134 res
= kCFCompareGreaterThan
;
1138 CFRelease(elements1
);
1139 CFRelease(elements2
);
1141 if (res
!= kCFCompareEqualTo
) {
1146 /* ... and, then sort by BSD interface name */
1147 if ((dev1
->entity_device
!= NULL
) && (dev2
->entity_device
!= NULL
)) {
1148 res
= CFStringCompare(dev1
->entity_device
, dev2
->entity_device
, 0);
1149 if (res
!= kCFCompareEqualTo
) {
1154 /* ... and lastly, sort by BSD interface unique identifier */
1155 if ((dev1
->entity_device_unique
!= NULL
) && (dev2
->entity_device_unique
!= NULL
)) {
1156 res
= CFStringCompare(dev1
->entity_device_unique
, dev2
->entity_device_unique
, 0);
1157 // if (res != kCFCompareEqualTo) {
1167 sort_interfaces(CFMutableArrayRef all_interfaces
)
1171 n
= CFArrayGetCount(all_interfaces
);
1176 CFArraySortValues(all_interfaces
, CFRangeMake(0, n
), _SCNetworkInterfaceCompare
, NULL
);
1183 __SCNetworkInterfaceOrder(SCNetworkInterfaceRef interface
)
1185 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
1187 return interfacePrivate
->sort_order
;
1192 #pragma mark Interface details
1196 IOCopyCFStringValue(CFTypeRef ioVal
)
1198 if (isA_CFString(ioVal
)) {
1199 return CFStringCreateCopy(NULL
, ioVal
);
1202 if (isA_CFData(ioVal
)) {
1203 return CFStringCreateWithCString(NULL
,
1204 (const char *)CFDataGetBytePtr(ioVal
),
1205 kCFStringEncodingUTF8
);
1213 IODictionaryCopyBSDName(CFDictionaryRef io_dict
)
1215 CFStringRef if_bsdName
;
1216 CFStringRef if_prefix
;
1217 CFNumberRef if_unit
;
1219 if_bsdName
= CFDictionaryGetValue(io_dict
, CFSTR(kIOBSDNameKey
));
1220 if (if_bsdName
!= NULL
) {
1221 return IOCopyCFStringValue(if_bsdName
);
1224 // no BSD name, get interface prefix and unit
1225 if_prefix
= CFDictionaryGetValue(io_dict
, CFSTR(kIOInterfaceNamePrefix
));
1226 if_unit
= CFDictionaryGetValue(io_dict
, CFSTR(kIOInterfaceUnit
));
1227 if (isA_CFString(if_prefix
) && isA_CFNumber(if_unit
)) {
1228 // if both prefix and unit available, construct BSD name
1229 if_bsdName
= CFStringCreateWithFormat(NULL
,
1241 IODictionaryCopyCFStringValue(CFDictionaryRef io_dict
, CFStringRef io_key
)
1245 ioVal
= CFDictionaryGetValue(io_dict
, io_key
);
1246 return IOCopyCFStringValue(ioVal
);
1251 IOStringValueHasPrefix(CFTypeRef ioVal
, CFStringRef prefix
)
1253 Boolean match
= FALSE
;
1254 CFIndex prefixLen
= CFStringGetLength(prefix
);
1255 CFStringRef str
= NULL
;
1257 if (!isA_CFString(ioVal
)) {
1258 if (isA_CFData(ioVal
)) {
1259 str
= CFStringCreateWithCStringNoCopy(NULL
,
1260 (const char *)CFDataGetBytePtr(ioVal
),
1261 kCFStringEncodingUTF8
,
1269 if ((ioVal
!= NULL
) &&
1270 (CFStringGetLength(ioVal
) >= prefixLen
) &&
1271 (CFStringCompareWithOptions(ioVal
,
1273 CFRangeMake(0, prefixLen
),
1274 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
)) {
1278 if (str
!= NULL
) CFRelease(str
);
1283 static const struct {
1284 const CFStringRef name
;
1285 const CFStringRef slot
;
1286 } slot_mappings
[] = {
1288 { CFSTR("A1") , CFSTR("1") },
1289 { CFSTR("B1") , CFSTR("2") },
1290 { CFSTR("C1") , CFSTR("3") },
1292 // Blue&White G3, Yikes G4
1293 { CFSTR("J12"), CFSTR("1") },
1294 { CFSTR("J11"), CFSTR("2") },
1295 { CFSTR("J10"), CFSTR("3") },
1296 { CFSTR("J9"), CFSTR("4") },
1299 { CFSTR("A") , CFSTR("1") },
1300 { CFSTR("B") , CFSTR("2") },
1301 { CFSTR("C") , CFSTR("3") },
1302 { CFSTR("D") , CFSTR("4") },
1304 // Digital Audio G4 (and later models)
1305 { CFSTR("1") , CFSTR("1") },
1306 { CFSTR("2") , CFSTR("2") },
1307 { CFSTR("3") , CFSTR("3") },
1308 { CFSTR("4") , CFSTR("4") },
1309 { CFSTR("5") , CFSTR("5") }
1313 static const CFStringRef slot_prefixes
[] = {
1314 CFSTR("thunderbolt slot "),
1320 static CF_RETURNS_RETAINED CFStringRef
1321 pci_slot(io_registry_entry_t interface
, CFTypeRef
*pci_slot_name
)
1324 io_registry_entry_t parent
;
1325 CFMutableStringRef slot
;
1326 CFTypeRef slot_name
;
1329 if (pci_slot_name
!= NULL
) *pci_slot_name
= NULL
;
1331 slot_name
= IORegistryEntryCreateCFProperty(interface
, CFSTR("AAPL,slot-name"), NULL
, 0);
1332 if (slot_name
!= NULL
) {
1335 slot
= CFStringCreateMutable(NULL
, 0);
1336 if (isA_CFString(slot_name
)) {
1337 if (pci_slot_name
!= NULL
) *pci_slot_name
= CFStringCreateCopy(NULL
, slot_name
);
1338 CFStringAppend(slot
, slot_name
);
1339 } else if (isA_CFData(slot_name
)) {
1340 if (pci_slot_name
!= NULL
) *pci_slot_name
= CFDataCreateCopy(NULL
, slot_name
);
1341 CFStringAppendCString(slot
,
1342 (const char *)CFDataGetBytePtr(slot_name
),
1343 kCFStringEncodingUTF8
);
1346 for (i
= 0; i
< sizeof(slot_prefixes
)/sizeof(slot_prefixes
[0]); i
++) {
1349 len
= CFStringGetLength(slot_prefixes
[i
]);
1350 if (CFStringGetLength(slot
) > len
) {
1351 (void) CFStringFindAndReplace(slot
,
1354 CFRangeMake(0, len
),
1355 kCFCompareCaseInsensitive
|kCFCompareAnchored
);
1359 for (i
= 0; i
< sizeof(slot_mappings
)/sizeof(slot_mappings
[0]); i
++) {
1360 if (CFStringCompare(slot
,
1361 slot_mappings
[i
].name
,
1362 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
1364 slot
= (CFMutableStringRef
)CFRetain(slot_mappings
[i
].slot
);
1369 CFRelease(slot_name
);
1372 kr
= IORegistryEntryGetParentEntry(interface
, kIOServicePlane
, &parent
);
1374 case kIOReturnSuccess
: {
1375 CFTypeRef parent_pci_slot_name
= NULL
;
1376 CFStringRef parent_slot
;
1378 parent_slot
= pci_slot(parent
, &parent_pci_slot_name
);
1379 if (parent_slot
!= NULL
) {
1380 if (slot
!= NULL
) CFRelease(slot
);
1381 slot
= (CFMutableStringRef
)parent_slot
;
1383 if (pci_slot_name
!= NULL
) {
1384 if (*pci_slot_name
!= NULL
) CFRelease(*pci_slot_name
);
1385 *pci_slot_name
= parent_pci_slot_name
;
1387 CFRelease(parent_pci_slot_name
);
1391 IOObjectRelease(parent
);
1394 case kIOReturnNoDevice
:
1395 // if we have hit the root node
1398 SCLog(TRUE
, LOG_DEBUG
, CFSTR("pci_slot IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr
);
1406 static CFComparisonResult
1407 compare_bsdNames(const void *val1
, const void *val2
, void *context
)
1409 CFStringRef bsd1
= (CFStringRef
)val1
;
1410 CFStringRef bsd2
= (CFStringRef
)val2
;
1412 return CFStringCompare(bsd1
, bsd2
, 0);
1416 static CF_RETURNS_RETAINED CFStringRef
1417 pci_port(CFTypeRef slot_name
, int ift
, CFStringRef bsdName
)
1420 CFStringRef port_name
= NULL
;
1421 CFMutableArrayRef port_names
;
1424 CFStringRef match_keys
[2];
1425 CFTypeRef match_vals
[2];
1426 CFDictionaryRef match_dict
;
1427 CFDictionaryRef matching
;
1428 io_registry_entry_t slot
;
1429 io_iterator_t slot_iterator
= MACH_PORT_NULL
;
1431 match_keys
[0] = CFSTR("AAPL,slot-name");
1432 match_vals
[0] = slot_name
;
1434 match_dict
= CFDictionaryCreate(NULL
,
1435 (const void **)match_keys
,
1436 (const void **)match_vals
,
1438 &kCFTypeDictionaryKeyCallBacks
,
1439 &kCFTypeDictionaryValueCallBacks
);
1441 match_keys
[0] = CFSTR(kIOProviderClassKey
);
1442 match_vals
[0] = CFSTR("IOPCIDevice");
1444 match_keys
[1] = CFSTR(kIOPropertyMatchKey
);
1445 match_vals
[1] = match_dict
;
1447 // note: the "matching" dictionary will be consumed by the following
1448 matching
= CFDictionaryCreate(NULL
,
1449 (const void **)match_keys
,
1450 (const void **)match_vals
,
1451 sizeof(match_keys
)/sizeof(match_keys
[0]),
1452 &kCFTypeDictionaryKeyCallBacks
,
1453 &kCFTypeDictionaryValueCallBacks
);
1454 CFRelease(match_dict
);
1456 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &slot_iterator
);
1457 if (kr
!= kIOReturnSuccess
) {
1458 SCLog(TRUE
, LOG_DEBUG
, CFSTR("pci_port IOServiceGetMatchingServices() failed, kr = 0x%x"), kr
);
1459 return MACH_PORT_NULL
;
1462 port_names
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1464 while ((slot
= IOIteratorNext(slot_iterator
)) != MACH_PORT_NULL
) {
1465 io_registry_entry_t child
;
1466 io_iterator_t child_iterator
= MACH_PORT_NULL
;
1468 kr
= IORegistryEntryCreateIterator(slot
,
1470 kIORegistryIterateRecursively
,
1472 if (kr
!= kIOReturnSuccess
) {
1473 SCLog(TRUE
, LOG_DEBUG
, CFSTR("pci_port IORegistryEntryCreateIterator() failed, kr = 0x%x"), kr
);
1474 CFRelease(port_names
);
1475 return MACH_PORT_NULL
;
1478 while ((child
= IOIteratorNext(child_iterator
)) != MACH_PORT_NULL
) {
1479 if (IOObjectConformsTo(child
, kIONetworkInterfaceClass
)) {
1480 CFMutableDictionaryRef interface_dict
= NULL
;
1482 (void) IORegistryEntryCreateCFProperties(child
, &interface_dict
, NULL
, kNilOptions
);
1483 if (interface_dict
!= NULL
) {
1484 CFNumberRef child_if_type
;
1485 int child_ift
= ift
;
1487 child_if_type
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceType
));
1488 if (child_if_type
!= NULL
) {
1489 if (!isA_CFNumber(child_if_type
) ||
1490 !CFNumberGetValue(child_if_type
, kCFNumberIntType
, &child_ift
)) {
1491 // assume that it's a match
1496 if (ift
== child_ift
) {
1497 CFStringRef if_bsdName
;
1499 if_bsdName
= IODictionaryCopyBSDName(interface_dict
);
1500 if (if_bsdName
!= NULL
) {
1501 CFArrayAppendValue(port_names
, if_bsdName
);
1502 CFRelease(if_bsdName
);
1506 CFRelease(interface_dict
);
1509 IOObjectRelease(child
);
1511 IOObjectRelease(child_iterator
);
1512 IOObjectRelease(slot
);
1514 IOObjectRelease(slot_iterator
);
1516 n
= CFArrayGetCount(port_names
);
1518 CFArraySortValues(port_names
, CFRangeMake(0, n
), compare_bsdNames
, NULL
);
1519 n
= CFArrayGetFirstIndexOfValue(port_names
, CFRangeMake(0, n
), bsdName
);
1520 if (n
!= kCFNotFound
) {
1521 port_name
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%ld"), n
+ 1);
1525 CFRelease(port_names
);
1531 pci_slot_info(io_registry_entry_t interface
, int ift
, CFStringRef
*slot_name
, CFStringRef
*port_name
)
1533 CFStringRef bsd_name
= NULL
;
1534 CFMutableDictionaryRef interface_dict
= NULL
;
1536 CFTypeRef pci_slot_name
;
1541 (void) IORegistryEntryCreateCFProperties(interface
, &interface_dict
, NULL
, kNilOptions
);
1542 if (interface_dict
!= NULL
) {
1543 bsd_name
= IODictionaryCopyBSDName(interface_dict
);
1544 CFRelease(interface_dict
);
1547 if (bsd_name
== NULL
) {
1551 *slot_name
= pci_slot(interface
, &pci_slot_name
);
1552 if (*slot_name
!= NULL
) {
1553 if (pci_slot_name
!= NULL
) {
1554 *port_name
= pci_port(pci_slot_name
, ift
, bsd_name
);
1555 CFRelease(pci_slot_name
);
1560 CFRelease(bsd_name
);
1566 isBuiltin(io_registry_entry_t interface
)
1570 slot
= pci_slot(interface
, NULL
);
1572 // interfaces which have a "slot" are not built-in
1582 isBluetoothBuiltin(Boolean
*haveController
)
1584 Boolean builtin
= FALSE
;
1585 io_object_t hciController
;
1586 io_iterator_t iter
= MACH_PORT_NULL
;
1589 kr
= IOServiceGetMatchingServices(masterPort
,
1590 IOServiceMatching("IOBluetoothHCIController"),
1592 if ((kr
!= kIOReturnSuccess
) || (iter
== MACH_PORT_NULL
)) {
1593 if (kr
!= kIOReturnSuccess
) {
1594 SCLog(TRUE
, LOG_DEBUG
, CFSTR("isBluetoothBuiltin IOServiceGetMatchingServices() failed, kr = 0x%x"), kr
);
1596 *haveController
= FALSE
;
1599 *haveController
= TRUE
;
1601 hciController
= IOIteratorNext(iter
);
1602 IOObjectRelease(iter
);
1603 if(hciController
!= MACH_PORT_NULL
) {
1604 #if !TARGET_IPHONE_SIMULATOR
1605 CFNumberRef idVendor
;
1607 idVendor
= IORegistryEntryCreateCFProperty(hciController
, CFSTR(kUSBVendorID
), NULL
, 0);
1608 if (idVendor
!= NULL
) {
1611 if (isA_CFNumber(idVendor
) &&
1612 CFNumberGetValue(idVendor
, kCFNumberIntType
, &idVendorVal
) &&
1613 (idVendorVal
== kIOUSBVendorIDAppleComputer
)) {
1617 CFRelease(idVendor
);
1619 #endif // !TARGET_IPHONE_SIMULATOR
1621 IOObjectRelease(hciController
);
1629 isThunderbolt(io_registry_entry_t interface
)
1633 val
= IORegistryEntrySearchCFProperty(interface
,
1635 CFSTR(kPCIThunderboltString
),
1637 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1648 processUSBInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1649 io_registry_entry_t interface
,
1650 CFDictionaryRef interface_dict
,
1651 io_registry_entry_t controller
,
1652 CFDictionaryRef controller_dict
,
1653 io_registry_entry_t bus
,
1654 CFDictionaryRef bus_dict
)
1656 #if !TARGET_IPHONE_SIMULATOR
1658 interfacePrivate
->usb
.name
= IORegistryEntrySearchCFProperty(interface
,
1660 CFSTR(kUSBProductString
),
1662 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1663 interfacePrivate
->usb
.vid
= IORegistryEntrySearchCFProperty(interface
,
1665 CFSTR(kUSBVendorID
),
1667 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1668 interfacePrivate
->usb
.pid
= IORegistryEntrySearchCFProperty(interface
,
1670 CFSTR(kUSBProductID
),
1672 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1673 #endif // !TARGET_IPHONE_SIMULATOR
1680 update_interface_name(SCNetworkInterfacePrivateRef interfacePrivate
,
1681 io_registry_entry_t interface
,
1684 Boolean updated
= FALSE
;
1687 // check if a "Product Name" has been provided
1688 val
= IORegistryEntrySearchCFProperty(interface
,
1690 CFSTR(kIOPropertyProductNameKey
),
1692 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1693 if ((val
== NULL
) && useUSBInfo
&& (interfacePrivate
->usb
.name
!= NULL
)) {
1694 // else, use "USB Product Name" if available
1695 val
= CFRetain(interfacePrivate
->usb
.name
);
1698 CFStringRef productName
;
1700 productName
= IOCopyCFStringValue(val
);
1703 if (productName
!= NULL
) {
1704 if (CFStringGetLength(productName
) > 0) {
1705 // if we have a [somewhat reasonable?] product name
1706 if (interfacePrivate
->name
!= NULL
) {
1707 CFRelease(interfacePrivate
->name
);
1709 interfacePrivate
->name
= CFRetain(productName
);
1710 if (interfacePrivate
->localized_name
!= NULL
) {
1711 CFRelease(interfacePrivate
->localized_name
);
1712 interfacePrivate
->localized_name
= NULL
;
1714 if (bundle
!= NULL
) {
1715 interfacePrivate
->localized_name
= copy_interface_string(bundle
, productName
, TRUE
);
1721 CFRelease(productName
);
1730 #pragma mark Interface enumeration
1733 typedef Boolean (*processInterface
)(SCNetworkInterfacePrivateRef interfacePrivate
,
1734 io_registry_entry_t interface
,
1735 CFDictionaryRef interface_dict
,
1736 io_registry_entry_t controller
,
1737 CFDictionaryRef controller_dict
,
1738 io_registry_entry_t bus
,
1739 CFDictionaryRef bus_dict
);
1743 merge_override(SCNetworkInterfacePrivateRef interfacePrivate
,
1744 io_registry_entry_t interface
,
1745 CFStringRef override
)
1750 key
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("Device%@Overrides"), override
);
1751 val
= IORegistryEntrySearchCFProperty(interface
,
1755 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1758 if (isA_CFDictionary(val
)) {
1759 if (interfacePrivate
->overrides
== NULL
) {
1760 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
1762 &kCFTypeDictionaryKeyCallBacks
,
1763 &kCFTypeDictionaryValueCallBacks
);
1765 CFDictionarySetValue(interfacePrivate
->overrides
, override
, val
);
1774 #define BT_PAN_NAME "Bluetooth PAN"
1775 #define BT_PAN_MAC BT_PAN_NAME " (MAC)"
1778 processNetworkInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1779 io_registry_entry_t interface
,
1780 CFDictionaryRef interface_dict
,
1781 io_registry_entry_t controller
,
1782 CFDictionaryRef controller_dict
,
1783 io_registry_entry_t bus
,
1784 CFDictionaryRef bus_dict
)
1794 num
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceType
));
1795 if (isA_CFNumber(num
) &&
1796 CFNumberGetValue(num
, kCFNumberIntType
, &ift
)) {
1797 interfacePrivate
->type
= CFRetain(num
);
1799 SCLog(TRUE
, LOG_DEBUG
, CFSTR("processNetworkInterface() failed, no interface type"));
1807 if (IOObjectConformsTo(controller
, "IO80211Controller") ||
1808 IOObjectConformsTo(controller
, "AirPortPCI" ) ||
1809 IOObjectConformsTo(controller
, "AirPortDriver" )) {
1810 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
1811 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1812 interfacePrivate
->sort_order
= kSortAirPort
;
1813 } else if (IOObjectConformsTo(controller
, "AppleThunderboltIPPort")) {
1814 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1815 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1816 interfacePrivate
->sort_order
= kSortThunderbolt
;
1817 } else if (IOObjectConformsTo(controller
, "IOBluetoothBNEPDriver")) {
1818 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1819 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1820 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
1821 } else if (IOObjectConformsTo(controller
, "AppleUSBEthernetHost")) {
1822 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1823 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1824 interfacePrivate
->sort_order
= kSortTethered
;
1825 } else if (IOObjectConformsTo(controller
, "AppleUSBCDCECMData")) {
1826 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1827 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1828 interfacePrivate
->sort_order
= kSortWWANEthernet
;
1831 if (interfacePrivate
->interface_type
== NULL
) {
1832 val
= IORegistryEntrySearchCFProperty(interface
,
1834 CFSTR(kIOUserEthernetInterfaceRoleKey
),
1836 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1838 if (isA_CFString(val
)) {
1839 if (CFEqual(val
, CFSTR(BT_PAN_NAME
))) {
1840 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1841 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1842 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
1843 } else if (CFEqual(val
, CFSTR("Bluetooth PAN-NAP"))) {
1844 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1845 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1846 interfacePrivate
->sort_order
= kSortBluetoothPAN_NAP
;
1847 } else if (CFEqual(val
, CFSTR("Bluetooth P2P"))) {
1848 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1849 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1850 interfacePrivate
->sort_order
= kSortBluetoothPAN_U
;
1858 if (interfacePrivate
->interface_type
== NULL
) {
1859 str
= IODictionaryCopyCFStringValue(bus_dict
, CFSTR("name"));
1861 if (CFEqual(str
, CFSTR("radio"))) {
1862 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
; // ??
1863 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1864 interfacePrivate
->sort_order
= kSortOtherWireless
;
1871 if (interfacePrivate
->interface_type
== NULL
) {
1872 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1873 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1874 interfacePrivate
->sort_order
= kSortEthernet
;
1876 // BOND support only enabled for ethernet devices
1877 interfacePrivate
->supportsBond
= TRUE
;
1880 // enable Bridge support
1881 interfacePrivate
->supportsBridge
= TRUE
;
1884 val
= isA_CFBoolean(CFDictionaryGetValue(interface_dict
, CFSTR(kIOBuiltin
)));
1886 val
= isA_CFBoolean(CFDictionaryGetValue(interface_dict
, CFSTR(kIOPrimaryInterface
)));
1889 interfacePrivate
->builtin
= CFBooleanGetValue(val
);
1891 interfacePrivate
->builtin
= isBuiltin(interface
);
1894 if (!interfacePrivate
->builtin
&&
1895 CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
)) {
1896 // always treat AirPort interfaces as built-in
1897 interfacePrivate
->builtin
= TRUE
;
1901 interfacePrivate
->location
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOLocation
));
1902 if ((interfacePrivate
->location
!= NULL
) &&
1903 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1904 CFRelease(interfacePrivate
->location
);
1905 interfacePrivate
->location
= NULL
;
1909 num
= CFDictionaryGetValue(controller_dict
, CFSTR(kIOFeatures
));
1910 if (isA_CFNumber(num
) &&
1911 CFNumberGetValue(num
, kCFNumberIntType
, & iVal
)) {
1912 if (iVal
& (kIONetworkFeatureHardwareVlan
| kIONetworkFeatureSoftwareVlan
)) {
1913 interfacePrivate
->supportsVLAN
= TRUE
;
1918 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
)) {
1919 interfacePrivate
->localized_key
= CFSTR("airport");
1920 } else if (interfacePrivate
->sort_order
== kSortThunderbolt
) {
1921 if ((interfacePrivate
->location
== NULL
) ||
1922 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1923 interfacePrivate
->localized_key
= CFSTR("thunderbolt");
1925 interfacePrivate
->localized_key
= CFSTR("multithunderbolt");
1926 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->location
);
1928 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_GN
) {
1929 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-gn");
1930 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_NAP
) {
1931 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-nap");
1932 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_U
) {
1933 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-u");
1934 } else if (interfacePrivate
->sort_order
== kSortOtherWireless
) {
1935 interfacePrivate
->localized_key
= CFSTR("wireless");
1936 interfacePrivate
->localized_arg1
= CFRetain(CFSTR("")); // ??
1937 } else if (interfacePrivate
->builtin
) {
1938 if ((interfacePrivate
->location
== NULL
) ||
1939 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1940 interfacePrivate
->localized_key
= CFSTR("ether");
1942 interfacePrivate
->localized_key
= CFSTR("multiether");
1943 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->location
);
1946 CFStringRef provider
;
1948 // check provider class
1949 provider
= IORegistryEntrySearchCFProperty(interface
,
1951 CFSTR(kIOProviderClassKey
),
1953 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1954 if (provider
!= NULL
) {
1955 if (CFEqual(provider
, CFSTR("IOPCIDevice"))) {
1956 CFStringRef port_name
;
1957 CFStringRef slot_name
;
1959 // set interface "name"
1960 if (!update_interface_name(interfacePrivate
, interface
, FALSE
) &&
1961 pci_slot_info(interface
, ift
, &slot_name
, &port_name
)) {
1962 if (isThunderbolt(interface
)) {
1963 if (port_name
== NULL
) {
1964 interfacePrivate
->localized_key
= CFSTR("thunderbolt-ether");
1965 interfacePrivate
->localized_arg1
= slot_name
;
1967 interfacePrivate
->localized_key
= CFSTR("thunderbolt-multiether");
1968 interfacePrivate
->localized_arg1
= slot_name
;
1969 interfacePrivate
->localized_arg2
= port_name
;
1973 if (port_name
== NULL
) {
1974 interfacePrivate
->localized_key
= CFSTR("pci-ether");
1975 interfacePrivate
->localized_arg1
= slot_name
;
1977 interfacePrivate
->localized_key
= CFSTR("pci-multiether");
1978 interfacePrivate
->localized_arg1
= slot_name
;
1979 interfacePrivate
->localized_arg2
= port_name
;
1984 io_registry_entry_t node
= interface
;
1986 while (provider
!= NULL
) {
1987 if (CFEqual(provider
, CFSTR("IOUSBDevice")) ||
1988 CFEqual(provider
, CFSTR("IOUSBInterface"))) {
1989 // get USB info (if available)
1990 processUSBInterface(interfacePrivate
,
1998 // set interface "name"
1999 if (!update_interface_name(interfacePrivate
, interface
, TRUE
)) {
2000 interfacePrivate
->localized_key
= CFSTR("usb-ether");
2001 interfacePrivate
->localized_arg1
= IODictionaryCopyBSDName(interface_dict
);
2006 if (node
== interface
) {
2008 } else if (node
== controller
) {
2014 CFRelease(provider
);
2015 provider
= IORegistryEntrySearchCFProperty(node
,
2017 CFSTR(kIOProviderClassKey
),
2019 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2022 if (interfacePrivate
->localized_key
== NULL
) {
2023 update_interface_name(interfacePrivate
, interface
, FALSE
);
2027 if (provider
!= NULL
) CFRelease(provider
);
2030 if (interfacePrivate
->localized_key
== NULL
) {
2031 // if no provider, not a PCI device, or no slot information
2032 interfacePrivate
->localized_key
= CFSTR("generic-ether");
2033 interfacePrivate
->localized_arg1
= IODictionaryCopyBSDName(interface_dict
);
2040 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeFireWire
;
2043 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeFireWire
;
2046 interfacePrivate
->builtin
= isBuiltin(interface
);
2049 interfacePrivate
->sort_order
= kSortFireWire
;
2052 if (interfacePrivate
->builtin
) {
2053 interfacePrivate
->localized_key
= CFSTR("firewire");
2055 CFStringRef port_name
;
2056 CFStringRef slot_name
;
2058 // set interface "name"
2059 if (!update_interface_name(interfacePrivate
, interface
, FALSE
) &&
2060 pci_slot_info(interface
, ift
, &slot_name
, &port_name
)) {
2061 if (isThunderbolt(interface
)) {
2062 if (port_name
== NULL
) {
2063 interfacePrivate
->localized_key
= CFSTR("thunderbolt-firewire");
2064 interfacePrivate
->localized_arg1
= slot_name
;
2066 interfacePrivate
->localized_key
= CFSTR("thunderbolt-multifirewire");
2067 interfacePrivate
->localized_arg1
= slot_name
;
2068 interfacePrivate
->localized_arg2
= port_name
;
2071 if (port_name
== NULL
) {
2072 interfacePrivate
->localized_key
= CFSTR("pci-firewire");
2073 interfacePrivate
->localized_arg1
= slot_name
;
2075 interfacePrivate
->localized_key
= CFSTR("pci-multifirewire");
2076 interfacePrivate
->localized_arg1
= slot_name
;
2077 interfacePrivate
->localized_arg2
= port_name
;
2085 SCLog(TRUE
, LOG_DEBUG
, CFSTR("processNetworkInterface() failed, unknown interface type = %d"), ift
);
2090 interfacePrivate
->entity_device
= IODictionaryCopyBSDName(interface_dict
);
2092 // Hardware (MAC) address
2093 data
= CFDictionaryGetValue(controller_dict
, CFSTR(kIOMACAddress
));
2094 if (isA_CFData(data
)) {
2095 interfacePrivate
->address
= CFRetain(data
);
2099 str
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceNamePrefix
));
2100 if (isA_CFString(str
)) {
2101 interfacePrivate
->prefix
= CFRetain(str
);
2105 num
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceUnit
));
2106 if (isA_CFNumber(num
) &&
2107 CFNumberGetValue(num
, kCFNumberIntType
, & iVal
)) {
2108 interfacePrivate
->unit
= CFRetain(num
);
2111 // configuration [PPP] template override (now deprecated, use NetworkConfigurationOverrides)
2112 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypePPP
);
2119 set_connection_script(SCNetworkInterfacePrivateRef interfacePrivate
, CFStringRef script
)
2121 CFDictionaryRef dict
;
2122 CFMutableDictionaryRef newDict
;
2124 if (interfacePrivate
->overrides
== NULL
) {
2125 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
2127 &kCFTypeDictionaryKeyCallBacks
,
2128 &kCFTypeDictionaryValueCallBacks
);
2131 dict
= CFDictionaryGetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
2133 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
2135 newDict
= CFDictionaryCreateMutable(NULL
,
2137 &kCFTypeDictionaryKeyCallBacks
,
2138 &kCFTypeDictionaryValueCallBacks
);
2140 if (script
!= NULL
) {
2141 CFDictionarySetValue(newDict
, kSCPropNetModemConnectionScript
, script
);
2143 CFDictionaryRemoveValue(newDict
, kSCPropNetModemConnectionScript
);
2145 if (CFDictionaryGetCount(newDict
) > 0) {
2146 CFDictionarySetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
, newDict
);
2148 CFDictionaryRemoveValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
2152 if (CFDictionaryGetCount(interfacePrivate
->overrides
) == 0) {
2153 CFRelease(interfacePrivate
->overrides
);
2154 interfacePrivate
->overrides
= NULL
;
2161 is_valid_connection_script(CFStringRef script
)
2163 char ccl
[MAXPATHLEN
];
2164 char path
[MAXPATHLEN
];
2165 NSSearchPathEnumerationState state
;
2167 (void) _SC_cfstring_to_cstring(script
,
2170 kCFStringEncodingUTF8
);
2172 state
= NSStartSearchPathEnumeration(NSLibraryDirectory
,
2173 NSLocalDomainMask
|NSSystemDomainMask
);
2174 while ((state
= NSGetNextSearchPathEnumeration(state
, path
))) {
2176 struct stat statBuf
;
2178 if (ccl
[0] == '/') {
2179 path
[0] = '\0'; // if modemCCL is a full path
2181 strlcat(path
, "/Modem Scripts/", sizeof(path
));
2183 strlcat(path
, ccl
, sizeof(path
));
2185 if (stat(path
, &statBuf
) != 0) {
2186 if (errno
== ENOENT
) {
2190 SCLog(TRUE
, LOG_DEBUG
,
2191 CFSTR("processSerialInterface stat() failed: %s"),
2195 if (S_ISREG(statBuf
.st_mode
)) {
2196 // if we have a valid CCL script
2200 #define BUNDLE_EXT ".ccl"
2201 #define BUNDLE_EXT_LEN sizeof(BUNDLE_EXT) - 1
2206 if ((n
<= BUNDLE_EXT_LEN
) ||
2207 (strstr(&path
[n
- BUNDLE_EXT_LEN
], BUNDLE_EXT
) == NULL
)) {
2208 strlcat(path
, BUNDLE_EXT
, sizeof(path
));
2209 if (stat(path
, &statBuf
) != 0) {
2210 if (errno
== ENOENT
) {
2214 SCLog(TRUE
, LOG_DEBUG
,
2215 CFSTR("processSerialInterface stat() failed: %s"),
2220 if (S_ISDIR(statBuf
.st_mode
)) {
2221 // if we have a valid CCL bundle
2231 processSerialInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
2232 io_registry_entry_t interface
,
2233 CFDictionaryRef interface_dict
,
2234 io_registry_entry_t controller
,
2235 CFDictionaryRef controller_dict
,
2236 io_registry_entry_t bus
,
2237 CFDictionaryRef bus_dict
)
2239 CFStringRef base
= NULL
;
2241 Boolean isModem
= FALSE
;
2242 Boolean isWWAN
= FALSE
;
2243 CFStringRef modemCCL
= NULL
;
2247 // check if initializing
2248 val
= IORegistryEntrySearchCFProperty(interface
,
2250 kSCNetworkInterfaceInitializingKey
,
2252 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2254 Boolean initializing
;
2256 initializing
= isA_CFBoolean(val
) && CFBooleanGetValue(val
);
2259 return FALSE
; // if this interface is still initializing
2264 val
= IORegistryEntrySearchCFProperty(interface
,
2268 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2270 isWWAN
= isA_CFBoolean(val
) && CFBooleanGetValue(val
);
2275 interfacePrivate
->entity_device
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOTTYDeviceKey
));
2276 if (interfacePrivate
->entity_device
== NULL
) {
2280 base
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOTTYBaseNameKey
));
2282 base
= CFRetain(interfacePrivate
->entity_device
);
2288 * Exclude ports named "irda" because otherwise the IrDA ports on the
2289 * original iMac (rev's A through D) show up as serial ports. Given
2290 * that only the rev A actually had an IrDA port, and Mac OS X doesn't
2291 * even support it, these ports definitely shouldn't be listed.
2293 if (CFStringCompare(base
,
2295 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
2299 if (IOStringValueHasPrefix(base
, CFSTR("bluetooth"))) {
2300 Boolean haveController
= FALSE
;
2303 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBluetooth
;
2304 interfacePrivate
->sort_order
= kSortBluetooth
;
2305 interfacePrivate
->builtin
= isBluetoothBuiltin(&haveController
);
2306 if (!haveController
) {
2307 // if device with no controller present
2310 } else if (IOStringValueHasPrefix(base
, CFSTR("irda-ircomm"))) {
2312 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIrDA
;
2313 interfacePrivate
->sort_order
= kSortIrDA
;
2314 } else if (isWWAN
) {
2316 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeWWAN
;
2317 interfacePrivate
->sort_order
= kSortWWAN
;
2320 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeModem
;
2321 interfacePrivate
->sort_order
= kSortModem
;
2324 val
= IORegistryEntrySearchCFProperty(interface
,
2326 CFSTR(kIODeviceSupportsHoldKey
),
2328 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2332 if (isA_CFNumber(val
) &&
2333 CFNumberGetValue(val
, kCFNumberSInt32Type
, &v92
)) {
2334 interfacePrivate
->modemIsV92
= (v92
== 1);
2341 interfacePrivate
->entity_type
= kSCEntNetModem
;
2343 // Entity (Hardware)
2344 ift
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOSerialBSDTypeKey
));
2345 if (!isA_CFString(ift
)) {
2349 if (CFEqual(ift
, CFSTR(kIOSerialBSDModemType
))) {
2353 if (CFEqual(base
, CFSTR("modem"))) {
2354 interfacePrivate
->builtin
= TRUE
;
2355 interfacePrivate
->sort_order
= kSortInternalModem
;
2356 } else if (CFEqual(base
, CFSTR("usbmodem"))) {
2357 interfacePrivate
->sort_order
= kSortUSBModem
;
2359 } else if (CFEqual(ift
, CFSTR(kIOSerialBSDRS232Type
))) {
2361 interfacePrivate
->sort_order
= kSortSerialPort
;
2366 // configuration [PPP] template override (now deprecated, use NetworkConfigurationOverrides)
2367 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypePPP
);
2369 // configuration [Modem] template override (now deprecated, use NetworkConfigurationOverrides)
2370 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypeModem
);
2372 // look for modem CCL, unique identifier
2373 if (interfacePrivate
->overrides
!= NULL
) {
2374 val
= CFDictionaryGetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
2376 CFStringRef uniqueID
;
2378 modemCCL
= CFDictionaryGetValue(val
, kSCPropNetModemConnectionScript
);
2379 modemCCL
= isA_CFString(modemCCL
);
2381 uniqueID
= CFDictionaryGetValue(val
, CFSTR("UniqueIdentifier"));
2382 uniqueID
= isA_CFString(uniqueID
);
2383 if (uniqueID
!= NULL
) {
2384 // retain the device's base name and the unique id
2385 CFRelease(interfacePrivate
->entity_device
);
2386 interfacePrivate
->entity_device
= CFRetain(base
);
2387 interfacePrivate
->entity_device_unique
= CFStringCreateCopy(NULL
, uniqueID
);
2392 // if not part of the NetworkConfigurationOverrides/DeviceModemOverrides, look
2393 // a bit harder for the modem CCL
2394 if (modemCCL
== NULL
) {
2395 val
= IORegistryEntrySearchCFProperty(interface
,
2399 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2401 modemCCL
= IOCopyCFStringValue(val
);
2402 if (modemCCL
!= NULL
) {
2403 set_connection_script(interfacePrivate
, modemCCL
);
2404 CFRelease(modemCCL
);
2412 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIrDA
)) {
2413 interfacePrivate
->localized_key
= CFSTR("irda");
2414 } else if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBluetooth
)) {
2415 interfacePrivate
->localized_key
= CFSTR("bluetooth");
2417 CFStringRef localized
= NULL
;
2418 CFStringRef name
= NULL
;
2419 CFMutableStringRef port
;
2421 port
= CFStringCreateMutableCopy(NULL
, 0, base
);
2422 CFStringLowercase(port
, NULL
);
2425 CFStringAppend(port
, CFSTR("-port"));
2428 // set non-localized name
2429 if (bundle
!= NULL
) {
2430 name
= copy_interface_string(bundle
, port
, FALSE
);
2433 if (!CFEqual(port
, name
)) {
2434 // if [English] localization available
2435 interfacePrivate
->name
= name
;
2437 // if no [English] localization available, use TTY base name
2439 interfacePrivate
->name
= CFStringCreateCopy(NULL
, base
);
2442 interfacePrivate
->name
= CFStringCreateCopy(NULL
, base
);
2445 // set localized name
2446 if (bundle
!= NULL
) {
2447 localized
= copy_interface_string(bundle
, port
, TRUE
);
2449 if (localized
!= NULL
) {
2450 if (!CFEqual(port
, localized
)) {
2451 // if localization available
2452 interfacePrivate
->localized_name
= localized
;
2454 // if no localization available, use TTY base name
2455 CFRelease(localized
);
2456 interfacePrivate
->localized_name
= CFStringCreateCopy(NULL
, base
);
2459 interfacePrivate
->localized_name
= CFStringCreateCopy(NULL
, base
);
2462 if (!isModem
|| !CFEqual(base
, CFSTR("modem"))) {
2463 // get USB info (if available)
2464 processUSBInterface(interfacePrivate
,
2472 // set interface "name"
2473 if (update_interface_name(interfacePrivate
, interface
, TRUE
)) {
2474 // if "ModemCCL" not provided, also check if the product/interface
2475 // name matches a CCL script
2476 if ((modemCCL
== NULL
) &&
2477 is_valid_connection_script(interfacePrivate
->name
)) {
2478 set_connection_script(interfacePrivate
, interfacePrivate
->name
);
2490 if (!ok
&& (interfacePrivate
->entity_device
!= NULL
)) {
2491 CFRelease(interfacePrivate
->entity_device
);
2492 interfacePrivate
->entity_device
= NULL
;
2494 if (base
!= NULL
) CFRelease(base
);
2501 __SC_IORegistryEntryCopyPath(io_registry_entry_t entry
, const io_name_t plane
)
2504 * Create a path for a registry entry.
2508 CFStringRef str
= NULL
;
2510 status
= IORegistryEntryGetPath(entry
, plane
, path
);
2511 if (status
== kIOReturnSuccess
) {
2512 str
= CFStringCreateWithCString(NULL
, path
, kCFStringEncodingUTF8
);
2513 } else if (status
== kIOReturnBadArgument
) {
2514 io_registry_entry_t parent
;
2516 status
= IORegistryEntryGetParentEntry(entry
, plane
, &parent
);
2517 if (status
== kIOReturnSuccess
) {
2518 CFStringRef str_parent
;
2520 str_parent
= __SC_IORegistryEntryCopyPath(parent
, plane
);
2521 if (str_parent
!= NULL
) {
2524 status
= IORegistryEntryGetNameInPlane(entry
, plane
, name
);
2525 if (status
== kIOReturnSuccess
) {
2528 status
= IORegistryEntryGetLocationInPlane(entry
, plane
, location
);
2529 if (status
== kIOReturnSuccess
) {
2530 str
= CFStringCreateWithFormat(NULL
,
2537 str
= CFStringCreateWithFormat(NULL
,
2545 CFRelease(str_parent
);
2548 IOObjectRelease(parent
);
2556 static SCNetworkInterfaceRef
2557 createInterface(io_registry_entry_t interface
, processInterface func
,
2558 CFStringRef hidden_key
)
2560 io_registry_entry_t bus
= MACH_PORT_NULL
;
2561 CFMutableDictionaryRef bus_dict
= NULL
;
2562 io_registry_entry_t controller
= MACH_PORT_NULL
;
2563 CFMutableDictionaryRef controller_dict
= NULL
;
2564 uint64_t entryID
= 0;
2565 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
2566 CFMutableDictionaryRef interface_dict
= NULL
;
2570 if (hidden_key
!= NULL
) {
2572 val
= IORegistryEntrySearchCFProperty(interface
,
2576 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2579 goto done
; // if this interface should not be exposed
2583 // get the dictionary associated with the [interface] node
2584 kr
= IORegistryEntryCreateCFProperties(interface
, &interface_dict
, NULL
, kNilOptions
);
2585 if (kr
!= kIOReturnSuccess
) {
2586 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryCreateCFProperties() failed, kr = 0x%x"), kr
);
2590 // get the controller node
2591 kr
= IORegistryEntryGetParentEntry(interface
, kIOServicePlane
, &controller
);
2592 if (kr
!= kIOReturnSuccess
) {
2593 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr
);
2597 // get the dictionary associated with the [controller] node
2598 kr
= IORegistryEntryCreateCFProperties(controller
, &controller_dict
, NULL
, kNilOptions
);
2599 if (kr
!= kIOReturnSuccess
) {
2600 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryCreateCFProperties() failed, kr = 0x%x"), kr
);
2605 kr
= IORegistryEntryGetParentEntry(controller
, kIOServicePlane
, &bus
);
2606 if (kr
!= kIOReturnSuccess
) {
2607 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr
);
2611 // get the dictionary associated with the [bus] node
2612 kr
= IORegistryEntryCreateCFProperties(bus
, &bus_dict
, NULL
, kNilOptions
);
2613 if (kr
!= kIOReturnSuccess
) {
2614 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryCreateCFProperties() failed, kr = 0x%x"), kr
);
2618 // get the registry entry ID
2619 kr
= IORegistryEntryGetRegistryEntryID(interface
, &entryID
);
2620 if (kr
!= kIOReturnSuccess
) {
2621 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryGetRegistryEntryID() failed, kr = 0x%x"), kr
);
2625 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
);
2626 assert(interfacePrivate
!= NULL
);
2627 interfacePrivate
->path
= __SC_IORegistryEntryCopyPath(interface
, kIOServicePlane
);
2628 interfacePrivate
->entryID
= entryID
;
2630 // configuration [PPP, Modem, DNS, IPv4, IPv6, Proxies, SMB] template overrides
2631 val
= IORegistryEntrySearchCFProperty(interface
,
2633 kSCNetworkInterfaceNetworkConfigurationOverridesKey
,
2635 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2637 if (isA_CFDictionary(val
)) {
2638 interfacePrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, val
);
2643 if ((*func
)(interfacePrivate
, interface
, interface_dict
, controller
, controller_dict
, bus
, bus_dict
)) {
2644 // get user-notification / auto-configuration preference
2645 val
= IORegistryEntrySearchCFProperty(interface
,
2647 kSCNetworkInterfaceConfigurationActionKey
,
2649 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2651 if (isA_CFString(val
)) {
2652 interfacePrivate
->configurationAction
= CFRetain(val
);
2657 // get HiddenConfiguration preference
2658 val
= IORegistryEntrySearchCFProperty(interface
,
2660 kSCNetworkInterfaceHiddenConfigurationKey
,
2662 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2664 interfacePrivate
->hidden
= TRUE
;
2668 CFRelease(interfacePrivate
);
2669 interfacePrivate
= NULL
;
2674 if (interface_dict
!= NULL
) CFRelease(interface_dict
);
2676 if (controller
!= MACH_PORT_NULL
) IOObjectRelease(controller
);
2677 if (controller_dict
!= NULL
) CFRelease(controller_dict
);
2679 if (bus
!= MACH_PORT_NULL
) IOObjectRelease(bus
);
2680 if (bus_dict
!= NULL
) CFRelease(bus_dict
);
2682 return (SCNetworkInterfaceRef
)interfacePrivate
;
2686 static CF_RETURNS_RETAINED CFArrayRef
2687 findMatchingInterfaces(CFDictionaryRef matching
, processInterface func
,
2688 CFStringRef hidden_key
)
2690 CFMutableArrayRef interfaces
;
2691 io_registry_entry_t interface
;
2693 io_iterator_t iterator
= MACH_PORT_NULL
;
2696 * A reference to the "matching" dictionary will be consumed by the
2697 * the call to IOServiceGetMatchingServices so we bump up the retain
2702 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &iterator
);
2703 if (kr
!= kIOReturnSuccess
) {
2704 SCLog(TRUE
, LOG_DEBUG
, CFSTR("findMatchingInterfaces IOServiceGetMatchingServices() failed, kr = 0x%x"), kr
);
2708 interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2710 while ((interface
= IOIteratorNext(iterator
)) != MACH_PORT_NULL
) {
2711 SCNetworkInterfaceRef match
;
2713 match
= createInterface(interface
, func
, hidden_key
);
2714 if (match
!= NULL
) {
2715 CFArrayAppendValue(interfaces
, match
);
2719 IOObjectRelease(interface
);
2722 IOObjectRelease(iterator
);
2729 #pragma mark helper functions
2733 findConfiguration(CFStringRef interface_type
)
2737 for (i
= 0; i
< sizeof(configurations
)/sizeof(configurations
[0]); i
++) {
2738 if (CFEqual(interface_type
, *configurations
[i
].interface_type
)) {
2749 __SCNetworkInterfaceGetDefaultConfigurationType(SCNetworkInterfaceRef interface
)
2751 CFIndex interfaceIndex
;
2752 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2754 if (interfacePrivate
->serviceID
== NULL
) {
2755 // if not associated with a service (yet)
2756 _SCErrorSet(kSCStatusInvalidArgument
);
2760 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2761 if (interfaceIndex
== kCFNotFound
) {
2762 // unknown interface type, use per-service configuration preferences
2763 return interfacePrivate
->interface_type
; // entity
2766 if (configurations
[interfaceIndex
].entity_hardware
!= NULL
) {
2767 // if configuration information can be associated with this interface type
2768 return *configurations
[interfaceIndex
].entity_hardware
;
2771 _SCErrorSet(kSCStatusInvalidArgument
);
2778 __SCNetworkInterfaceIsValidExtendedConfigurationType(SCNetworkInterfaceRef interface
,
2779 CFStringRef extendedType
,
2780 Boolean requirePerInterface
)
2782 CFStringRef defaultType
;
2783 CFIndex extendedIndex
;
2784 CFIndex interfaceIndex
;
2785 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2786 Boolean isL2TP
= FALSE
;
2789 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
2790 if (defaultType
== NULL
) {
2794 if (CFEqual(extendedType
, defaultType
)) {
2795 // extended and default configuration types cannot conflict
2799 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2800 if (interfaceIndex
== kCFNotFound
) {
2801 // configuration information for unknown interface type's
2802 // are stored along with the service and we don't allow
2803 // per-service extended configurations
2807 if (CFEqual(extendedType
, kSCEntNetIPSec
)) {
2808 CFStringRef interfaceType
;
2810 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
2811 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
2812 SCNetworkInterfaceRef child
;
2814 child
= SCNetworkInterfaceGetInterface(interface
);
2815 if (child
!= NULL
) {
2816 interfaceType
= SCNetworkInterfaceGetInterfaceType(child
);
2817 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
2824 if (requirePerInterface
&&
2825 !configurations
[interfaceIndex
].per_interface_config
&&
2827 // we don't allow per-service extended configurations (except
2828 // that we do allow IPSec as an extended type for PPP->L2TP)
2832 extendedIndex
= findConfiguration(extendedType
);
2833 if ((extendedIndex
!= kCFNotFound
) && !isL2TP
) {
2834 // extended type cannot match a known interface type (except
2835 // that we do allow IPSec as an extended type for PPP->L2TP)
2841 * Do we match specific/known extended configuration types (e.g. EAPOL)
2842 * and ensure that any non-standard extended configuration types be of
2843 * the form com.myCompany.myType?
2852 _SCErrorSet(kSCStatusInvalidArgument
);
2859 CFStringRef defaultType
;
2860 CFMutableArrayRef types
;
2861 } extendedConfiguration
, *extendedConfigurationRef
;
2865 __addExtendedConfigurationType(const void *key
, const void *value
, void *context
)
2867 CFStringRef extendedType
= (CFStringRef
)key
;
2868 extendedConfigurationRef myContextRef
= (extendedConfigurationRef
)context
;
2870 if (CFEqual(extendedType
, myContextRef
->defaultType
)) {
2871 // do not include the default configuration type
2875 if (CFArrayContainsValue(myContextRef
->types
,
2876 CFRangeMake(0, CFArrayGetCount(myContextRef
->types
)),
2878 // if extendedType already has already been added
2882 CFArrayAppendValue(myContextRef
->types
, extendedType
);
2888 static CF_RETURNS_RETAINED CFArrayRef
2889 extendedConfigurationTypes(SCNetworkInterfaceRef interface
)
2892 CFIndex interfaceIndex
;
2893 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2894 extendedConfiguration myContext
;
2895 SCNetworkServiceRef service
;
2899 myContext
.defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
2900 if (myContext
.defaultType
== NULL
) {
2901 myContext
.types
= NULL
;
2905 myContext
.types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2907 if (interfacePrivate
->serviceID
== NULL
) {
2908 // if not associated with a service (yet)
2912 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2913 if (interfaceIndex
== kCFNotFound
) {
2914 // we don't allow per-service extended configurations
2918 if (!configurations
[interfaceIndex
].per_interface_config
) {
2919 // known interface type but we still don't allow
2920 // per-service extended configurations
2924 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
2925 interfacePrivate
->prefs
,
2926 interfacePrivate
->serviceID
,
2929 sets
= SCNetworkSetCopyAll(interfacePrivate
->prefs
);
2930 n
= (sets
!= NULL
) ? CFArrayGetCount(sets
) : 0;
2932 for (i
= 0; i
< n
; i
++) {
2933 CFDictionaryRef configs
;
2936 CFArrayRef services
;
2937 SCNetworkSetRef set
;
2939 set
= CFArrayGetValueAtIndex(sets
, i
);
2940 services
= SCNetworkSetCopyServices(set
);
2941 found
= CFArrayContainsValue(services
,
2942 CFRangeMake(0, CFArrayGetCount(services
)),
2944 CFRelease(services
);
2950 // add stored extended configuration types
2951 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
2952 SCNetworkSetGetSetID(set
), // set
2953 interfacePrivate
->entity_device
, // service
2955 configs
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
2957 if (isA_CFDictionary(configs
)) {
2958 CFDictionaryApplyFunction(configs
,
2959 __addExtendedConfigurationType
,
2963 // add not-yet-stored extended configuration types
2964 if (interfacePrivate
->unsaved
!= NULL
) {
2965 CFDictionaryApplyFunction(interfacePrivate
->unsaved
,
2966 __addExtendedConfigurationType
,
2974 if (sets
!= NULL
) CFRelease(sets
);
2978 return myContext
.types
;
2983 copyConfigurationPaths(SCNetworkInterfacePrivateRef interfacePrivate
,
2984 CFStringRef extendedType
)
2986 CFMutableArrayRef array
;
2988 CFIndex interfaceIndex
;
2991 SCNetworkServiceRef service
;
2994 array
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2996 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2997 if (interfaceIndex
== kCFNotFound
) {
2998 // unknown interface type, use per-service configuration preferences
2999 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
3000 interfacePrivate
->serviceID
, // service
3001 extendedType
); // entity
3002 CFArrayAppendValue(array
, path
);
3007 if (!configurations
[interfaceIndex
].per_interface_config
) {
3008 // known interface type, per-service configuration preferences
3009 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
3010 interfacePrivate
->serviceID
, // service
3011 extendedType
); // entity
3012 CFArrayAppendValue(array
, path
);
3017 // known interface type, per-interface configuration preferences
3019 // 1. look for all sets which contain the associated service
3020 // 2. add a per-set path for the interface configuration for
3023 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
3024 interfacePrivate
->prefs
,
3025 interfacePrivate
->serviceID
,
3026 (SCNetworkInterfaceRef
)interfacePrivate
);
3028 sets
= SCNetworkSetCopyAll(interfacePrivate
->prefs
);
3029 n
= (sets
!= NULL
) ? CFArrayGetCount(sets
) : 0;
3031 for (i
= 0; i
< n
; i
++) {
3032 CFArrayRef services
;
3033 SCNetworkSetRef set
;
3035 set
= CFArrayGetValueAtIndex(sets
, i
);
3036 services
= SCNetworkSetCopyServices(set
);
3037 if (CFArrayContainsValue(services
,
3038 CFRangeMake(0, CFArrayGetCount(services
)),
3040 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
3041 SCNetworkSetGetSetID(set
), // set
3042 interfacePrivate
->entity_device
, // service
3043 extendedType
); // entity
3044 CFArrayAppendValue(array
, path
);
3047 CFRelease(services
);
3050 if (CFArrayGetCount(array
) == 0) {
3056 if (sets
!= NULL
) CFRelease(sets
);
3062 #pragma mark SCNetworkInterface <--> preferences entity
3067 __SCNetworkInterfaceCopyInterfaceEntity(SCNetworkInterfaceRef interface
)
3069 CFMutableDictionaryRef entity
;
3070 CFIndex interfaceIndex
;
3071 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3073 entity
= CFDictionaryCreateMutable(NULL
,
3075 &kCFTypeDictionaryKeyCallBacks
,
3076 &kCFTypeDictionaryValueCallBacks
);
3077 if (interfacePrivate
->entity_type
!= NULL
) {
3078 CFDictionarySetValue(entity
,
3079 kSCPropNetInterfaceType
,
3080 interfacePrivate
->entity_type
);
3082 if (interfacePrivate
->entity_subtype
!= NULL
) {
3083 CFDictionarySetValue(entity
,
3084 kSCPropNetInterfaceSubType
,
3085 interfacePrivate
->entity_subtype
);
3087 if (interfacePrivate
->entity_device
!= NULL
) {
3088 CFDictionarySetValue(entity
,
3089 kSCPropNetInterfaceDeviceName
,
3090 interfacePrivate
->entity_device
);
3092 if (interfacePrivate
->entity_device_unique
!= NULL
) {
3093 CFDictionarySetValue(entity
,
3094 CFSTR("DeviceUniqueIdentifier"),
3095 interfacePrivate
->entity_device_unique
);
3097 if (interfacePrivate
->hidden
) {
3098 CFDictionarySetValue(entity
,
3099 kSCNetworkInterfaceHiddenConfigurationKey
,
3103 // match the "hardware" with the lowest layer
3105 SCNetworkInterfaceRef nextInterface
;
3107 nextInterface
= SCNetworkInterfaceGetInterface(interface
);
3108 if (nextInterface
== NULL
) {
3112 interface
= nextInterface
;
3114 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3116 if (CFEqual(interface
, kSCNetworkInterfaceIPv4
)) {
3120 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
3121 if (interfaceIndex
!= kCFNotFound
) {
3122 if (configurations
[interfaceIndex
].entity_hardware
!= NULL
) {
3123 CFDictionarySetValue(entity
,
3124 kSCPropNetInterfaceHardware
,
3125 *configurations
[interfaceIndex
].entity_hardware
);
3128 CFDictionarySetValue(entity
,
3129 kSCPropNetInterfaceHardware
,
3130 interfacePrivate
->interface_type
);
3133 // add the localized display name (which will only be used when/if the
3134 // interface is removed from the system)
3135 CFDictionarySetValue(entity
,
3136 kSCPropUserDefinedName
,
3137 SCNetworkInterfaceGetLocalizedDisplayName(interface
));
3139 // note that this is a V.92 capable modem
3140 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeModem
) &&
3141 interfacePrivate
->modemIsV92
) {
3145 num
= CFNumberCreate(NULL
, kCFNumberIntType
, &one
);
3146 CFDictionarySetValue(entity
,
3147 kSCPropNetInterfaceSupportsModemOnHold
,
3156 static SCNetworkInterfaceRef
3157 findInterface(CFArrayRef interfaces
, CFStringRef match_if
)
3162 n
= CFArrayGetCount(interfaces
);
3163 for (i
= 0; i
< n
; i
++) {
3164 SCNetworkInterfaceRef interface
= CFArrayGetValueAtIndex(interfaces
, i
);
3165 CFStringRef interfaceName
;
3167 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
3168 if ((interfaceName
!= NULL
) && CFEqual(interfaceName
, match_if
)) {
3169 CFRetain(interface
);
3177 #if !TARGET_OS_IPHONE
3178 static SCNetworkInterfaceRef
3179 findBondInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
3182 SCNetworkInterfaceRef interface
= NULL
;
3184 if (prefs
== NULL
) {
3188 // check if the interface is an Ethernet Bond
3189 bonds
= SCBondInterfaceCopyAll(prefs
);
3190 if (bonds
!= NULL
) {
3191 interface
= findInterface(bonds
, ifDevice
);
3196 #endif // !TARGET_OS_IPHONE
3198 static SCNetworkInterfaceRef
3199 findBridgeInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
3202 SCNetworkInterfaceRef interface
= NULL
;
3204 if (prefs
== NULL
) {
3208 // check if the interface is an bridge
3209 bridges
= SCBridgeInterfaceCopyAll(prefs
);
3210 if (bridges
!= NULL
) {
3211 interface
= findInterface(bridges
, ifDevice
);
3217 static SCNetworkInterfaceRef
3218 findVLANInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
3220 SCNetworkInterfaceRef interface
= NULL
;
3223 if (prefs
== NULL
) {
3227 // check if the interface is a VLAN
3228 vlans
= SCVLANInterfaceCopyAll(prefs
);
3229 if (vlans
!= NULL
) {
3230 interface
= findInterface(vlans
, ifDevice
);
3240 static CFMutableDictionaryRef
3241 copy_ppp_entity(CFStringRef bsdName
)
3243 CFMutableDictionaryRef entity
= NULL
;
3244 CFStringRef pattern
;
3245 CFMutableArrayRef patterns
;
3246 CFDictionaryRef dict
;
3248 patterns
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3249 pattern
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, kSCDynamicStoreDomainState
, kSCCompAnyRegex
, kSCEntNetPPP
);
3250 CFArrayAppendValue(patterns
, pattern
);
3252 pattern
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, kSCDynamicStoreDomainSetup
, kSCCompAnyRegex
, kSCEntNetInterface
);
3253 CFArrayAppendValue(patterns
, pattern
);
3255 dict
= SCDynamicStoreCopyMultiple(NULL
, NULL
, patterns
);
3256 CFRelease(patterns
);
3259 const void * keys_q
[N_QUICK
];
3260 const void ** keys
= keys_q
;
3262 const void * vals_q
[N_QUICK
];
3263 const void ** vals
= vals_q
;
3265 n
= CFDictionaryGetCount(dict
);
3266 if (n
> (CFIndex
)(sizeof(keys_q
) / sizeof(CFTypeRef
))) {
3267 keys
= CFAllocatorAllocate(NULL
, n
* sizeof(CFTypeRef
), 0);
3268 vals
= CFAllocatorAllocate(NULL
, n
* sizeof(CFTypeRef
), 0);
3270 CFDictionaryGetKeysAndValues(dict
, keys
, vals
);
3271 for (i
= 0; i
< n
; i
++) {
3272 CFArrayRef components
;
3273 CFStringRef interfaceKey
;
3274 CFDictionaryRef interfaceVal
;
3276 CFStringRef pppKey
= (CFStringRef
)keys
[i
];
3277 CFDictionaryRef pppVal
= (CFDictionaryRef
)vals
[i
];
3278 CFStringRef serviceID
;
3280 if (!CFStringHasSuffix(pppKey
, kSCEntNetPPP
) ||
3281 !CFDictionaryGetValueIfPresent(pppVal
, kSCPropInterfaceName
, (const void **)&ifName
) ||
3282 !CFEqual(bsdName
, ifName
)) {
3283 // if not matching PPP interface
3287 components
= CFStringCreateArrayBySeparatingStrings(NULL
, pppKey
, CFSTR("/"));
3288 serviceID
= CFArrayGetValueAtIndex(components
, 3);
3289 interfaceKey
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, kSCDynamicStoreDomainSetup
, serviceID
, kSCEntNetInterface
);
3290 interfaceVal
= CFDictionaryGetValue(dict
, interfaceKey
);
3291 CFRelease(interfaceKey
);
3292 CFRelease(components
);
3293 if (interfaceVal
!= NULL
) {
3294 entity
= CFDictionaryCreateMutableCopy(NULL
, 0, interfaceVal
);
3298 if (keys
!= keys_q
) {
3299 CFAllocatorDeallocate(NULL
, keys
);
3300 CFAllocatorDeallocate(NULL
, vals
);
3310 SCNetworkInterfaceRef
3311 _SCNetworkInterfaceCreateWithBSDName(CFAllocatorRef allocator
,
3312 CFStringRef bsdName
,
3315 CFMutableDictionaryRef entity
= NULL
;
3317 SCNetworkInterfaceRef interface
;
3319 bzero(&ifr
, sizeof(ifr
));
3320 if (_SC_cfstring_to_cstring(bsdName
, ifr
.ifr_name
, sizeof(ifr
.ifr_name
), kCFStringEncodingASCII
) != NULL
) {
3323 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
3325 if (ioctl(s
, SIOCGIFFLAGS
, (caddr_t
)&ifr
) == -1) {
3331 if ((ifr
.ifr_flags
& IFF_POINTOPOINT
) != 0) {
3333 entity
= copy_ppp_entity(bsdName
);
3337 if (entity
== NULL
) {
3338 entity
= CFDictionaryCreateMutable(NULL
,
3340 &kCFTypeDictionaryKeyCallBacks
,
3341 &kCFTypeDictionaryValueCallBacks
);
3342 CFDictionarySetValue(entity
, kSCPropNetInterfaceDeviceName
, bsdName
);
3345 #if !TARGET_OS_IPHONE
3346 if ((flags
& kIncludeBondInterfaces
) == 0) {
3347 CFDictionarySetValue(entity
, CFSTR("_NO_BOND_INTERFACES_"), kCFBooleanTrue
);
3349 #endif // !TARGET_OS_IPHONE
3351 if ((flags
& kIncludeBridgeInterfaces
) == 0) {
3352 CFDictionarySetValue(entity
, CFSTR("_NO_BRIDGE_INTERFACES_"), kCFBooleanTrue
);
3355 if ((flags
& kIncludeVLANInterfaces
) == 0) {
3356 CFDictionarySetValue(entity
, CFSTR("_NO_VLAN_INTERFACES_"), kCFBooleanTrue
);
3359 interface
= _SCNetworkInterfaceCreateWithEntity(NULL
, entity
, NULL
);
3367 _SCNetworkInterfaceCopyPrefixFromBSDName(CFStringRef bsdName
)
3369 CFMutableStringRef interfacePrefix
= NULL
;
3373 if (isA_CFString(bsdName
) == NULL
) {
3374 SCLog(TRUE
, LOG_DEBUG
, CFSTR("_SCNetworkInterfaceCopyPrefixFromBSDName: bsdName is NULL or not of the correct type"));
3378 interfacePrefix
= CFStringCreateMutableCopy(NULL
, 0, bsdName
);
3379 length
= CFStringGetLength(interfacePrefix
);
3381 while (length
> 0) {
3382 lastChar
= CFStringGetCharacterAtIndex(interfacePrefix
, length
- 1);
3383 if (lastChar
>= '0' && lastChar
<= '9') {
3384 CFStringDelete(interfacePrefix
,
3385 CFRangeMake(length
-1, 1));
3390 length
= CFStringGetLength(interfacePrefix
);
3393 return interfacePrefix
;
3398 __SCNetworkInterfaceSetIOInterfacePrefix(SCNetworkInterfaceRef interface
,
3399 CFStringRef prefix
);
3403 __SCNetworkInterfaceUpdateBSDName(SCNetworkInterfaceRef interface
, CFStringRef currentBSDName
, CFStringRef newBSDName
)
3405 Boolean success
= FALSE
;
3406 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3408 if (isA_SCNetworkInterface(interface
) == NULL
) {
3409 SCLog(TRUE
, LOG_DEBUG
, CFSTR("__SCNetworkInterfaceUpdateBSDName: interface is NULL or not of the correct type"));
3413 if (CFEqual(currentBSDName
, newBSDName
)) {
3414 SCLog(TRUE
, LOG_DEBUG
, CFSTR("__SCNetworkInterfaceUpdateBSDName: bsdName (%@) is equal to interfacePrivate->entity_device (%@)"), currentBSDName
, newBSDName
);
3418 if (interfacePrivate
->entity_device
!= NULL
) {
3419 CFRelease(interfacePrivate
->entity_device
);
3421 interfacePrivate
->entity_device
= CFRetain(newBSDName
);
3429 __SCNetworkInterfaceUpdateIOPath(SCNetworkInterfaceRef interface
)
3431 Boolean success
= FALSE
;
3432 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3433 CFStringRef oldPath
= NULL
;
3434 CFStringRef newPath
= NULL
;
3436 // Using the BSD Name update the path
3437 oldPath
= interfacePrivate
->path
;
3438 if (isA_CFString(oldPath
) == NULL
) {
3441 newPath
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("Migrated_From: %@"), oldPath
);
3442 if (interfacePrivate
->path
!= NULL
) {
3443 CFRelease(interfacePrivate
->path
);
3445 interfacePrivate
->path
= CFRetain(newPath
);
3449 if (newPath
!= NULL
) {
3457 __SCNetworkInterfaceSetIOInterfacePrefix (SCNetworkInterfaceRef interface
,
3460 SCNetworkInterfacePrivateRef interfacePrivate
;
3462 if (isA_CFString(prefix
) == NULL
) {
3466 interfacePrivate
= (SCNetworkInterfacePrivateRef
) interface
;
3470 if (interfacePrivate
->prefix
!= NULL
) {
3471 CFRelease(interfacePrivate
->prefix
);
3474 interfacePrivate
->prefix
= prefix
;
3481 __SCNetworkInterfaceSetIOInterfaceUnit (SCNetworkInterfaceRef interface
,
3484 SCNetworkInterfacePrivateRef interfacePrivate
;
3485 CFStringRef newBSDName
= NULL
;
3486 CFStringRef oldBSDName
= NULL
;
3488 if (isA_CFNumber(unit
) == NULL
) {
3491 interfacePrivate
= (SCNetworkInterfacePrivateRef
) interface
;
3493 oldBSDName
= SCNetworkInterfaceGetBSDName(interface
);
3495 if (interfacePrivate
->prefix
== NULL
) {
3496 if (isA_CFString(interfacePrivate
->entity_device
) != NULL
) {
3497 CFStringRef interfaceNamePrefix
= _SCNetworkInterfaceCopyPrefixFromBSDName(interfacePrivate
->entity_device
);
3498 if (interfaceNamePrefix
== NULL
) {
3499 SCLog(TRUE
, LOG_DEBUG
, CFSTR("__SCNetworkInterfaceSetIOInterfaceUnit: interfaceNamePrefix is NULL"));
3502 __SCNetworkInterfaceSetIOInterfacePrefix(interface
, interfaceNamePrefix
);
3503 CFRelease(interfaceNamePrefix
);
3508 if (interfacePrivate
->prefix
!= NULL
) {
3509 newBSDName
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@%@"), interfacePrivate
->prefix
, unit
);
3512 // Update the BSD Name
3513 if ((newBSDName
== NULL
) ||
3514 (__SCNetworkInterfaceUpdateBSDName(interface
, oldBSDName
, newBSDName
) == FALSE
)) {
3515 SCLog(_sc_debug
, LOG_DEBUG
, CFSTR("__SCNetworkInterfaceSetIOInterfaceUnit: Update BSD Name Failed"));
3519 if (__SCNetworkInterfaceUpdateIOPath(interface
) == FALSE
) {
3520 SCLog(_sc_debug
, LOG_DEBUG
, CFSTR("__SCNetworkInterfaceSetIOInterfaceUnit: Update IO Path Failed"));
3524 if (interfacePrivate
->unit
!= NULL
) {
3525 CFRelease(interfacePrivate
->unit
);
3527 interfacePrivate
->unit
= unit
;
3530 if (newBSDName
!= NULL
) {
3531 CFRelease(newBSDName
);
3539 __SCNetworkInterfaceCopyStorageEntity(SCNetworkInterfaceRef interface
)
3541 CFMutableDictionaryRef interface_entity
= NULL
;
3542 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3543 CFBooleanRef active
= NULL
;
3544 CFStringRef bsdName
= NULL
;
3545 CFBooleanRef builtin
= NULL
;
3546 CFStringRef interfaceNamePrefix
= NULL
;
3547 CFNumberRef interfaceType
= NULL
;
3548 CFNumberRef interfaceUnit
= NULL
;
3549 CFDataRef macAddress
= NULL
;
3550 CFStringRef pathMatch
= NULL
;
3551 CFDictionaryRef info
= NULL
;
3552 CFStringRef type
= NULL
;
3554 if (interfacePrivate
->active
== TRUE
) {
3555 active
= kCFBooleanTrue
;
3558 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
3559 if (isA_CFString(bsdName
) == NULL
) {
3563 builtin
= interfacePrivate
->builtin
? kCFBooleanTrue
: kCFBooleanFalse
;
3564 interfaceNamePrefix
= _SCNetworkInterfaceGetIOInterfaceNamePrefix(interface
);
3565 if (isA_CFString(interfaceNamePrefix
) == NULL
) {
3569 interfaceType
= _SCNetworkInterfaceGetIOInterfaceType(interface
);
3570 if (isA_CFNumber(interfaceType
) == NULL
) {
3574 interfaceUnit
= _SCNetworkInterfaceGetIOInterfaceUnit(interface
);
3575 if (isA_CFNumber(interfaceUnit
) == NULL
) {
3579 macAddress
= _SCNetworkInterfaceGetHardwareAddress(interface
);
3580 if (isA_CFData(macAddress
) == NULL
) {
3584 pathMatch
= _SCNetworkInterfaceGetIOPath(interface
);
3585 if (isA_CFString(pathMatch
) == NULL
) {
3589 info
= _SCNetworkInterfaceCopyInterfaceInfo(interface
);
3590 if (isA_CFDictionary(info
) == NULL
) {
3594 type
= SCNetworkInterfaceGetInterfaceType(interface
);
3595 if (isA_CFString(type
) == NULL
) {
3599 interface_entity
= CFDictionaryCreateMutable(NULL
, 0,
3600 &kCFTypeDictionaryKeyCallBacks
,
3601 &kCFTypeDictionaryValueCallBacks
);
3603 if (isA_CFBoolean(active
) != NULL
) {
3604 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceActive
), active
);
3607 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceBSDName
), bsdName
);
3608 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOBuiltin
), builtin
);
3609 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceNamePrefix
), interfaceNamePrefix
);
3610 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceType
), interfaceType
);
3611 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceUnit
), interfaceUnit
);
3612 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOMACAddress
), macAddress
);
3613 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOPathMatch
), pathMatch
);
3614 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceInfo
), info
);
3615 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceType
), type
);
3620 return interface_entity
;
3625 __SCNetworkInterfaceSetService(SCNetworkInterfaceRef interface
,
3626 SCNetworkServiceRef service
)
3628 SCNetworkInterfacePrivateRef interfacePrivate
;
3629 SCNetworkServicePrivateRef servicePrivate
;
3631 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3632 if (interfacePrivate
->prefs
!= NULL
) {
3633 CFRelease(interfacePrivate
->prefs
);
3634 interfacePrivate
->prefs
= NULL
;
3636 if (interfacePrivate
->serviceID
!= NULL
) {
3637 CFRelease(interfacePrivate
->serviceID
);
3638 interfacePrivate
->serviceID
= NULL
;
3641 servicePrivate
= (SCNetworkServicePrivateRef
)service
;
3642 if (servicePrivate
->prefs
!= NULL
) {
3643 interfacePrivate
->prefs
= CFRetain(servicePrivate
->prefs
);
3645 if (servicePrivate
->serviceID
!= NULL
) {
3646 interfacePrivate
->serviceID
= CFRetain(servicePrivate
->serviceID
);
3655 __SCNetworkInterfaceMatchesName(CFStringRef name
, CFStringRef key
)
3660 if (bundle
== NULL
) {
3665 if (!isA_CFString(name
)) {
3666 // if no interface "name"
3670 // check non-localized name for a match
3671 str
= copy_interface_string(bundle
, key
, FALSE
);
3673 match
= CFEqual(name
, str
);
3680 // check localized name for a match
3681 str
= copy_interface_string(bundle
, key
, TRUE
);
3683 match
= CFEqual(name
, str
);
3694 #define kInterfaceTypeEthernetValue 6
3695 #define kInterfaceTypeFirewireValue 144
3698 static SCNetworkInterfaceRef
3699 __SCNetworkInterfaceCreateWithStorageEntity (CFAllocatorRef allocator
,
3700 CFDictionaryRef interface_entity
,
3701 SCPreferencesRef prefs
)
3703 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
3704 CFBooleanRef active
= NULL
;
3705 CFStringRef bsdName
= NULL
;
3706 CFBooleanRef ioBuiltin
= NULL
;
3707 CFStringRef ioInterfaceNamePrefix
= NULL
;
3708 CFNumberRef ioInterfaceType
= NULL
;
3709 int ioInterfaceTypeNum
;
3710 CFNumberRef ioInterfaceUnit
= NULL
;
3711 CFDataRef ioMACAddress
= NULL
;
3712 CFStringRef ioPathMatch
= NULL
;
3713 CFDictionaryRef SCNetworkInterfaceInfo
= NULL
;
3714 CFStringRef userDefinedName
= NULL
;
3715 CFStringRef usbProductName
= NULL
;
3716 CFNumberRef idProduct
= NULL
;
3717 CFNumberRef idVendor
= NULL
;
3718 CFStringRef type
= NULL
;
3720 /* initialize runtime */
3721 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
3723 if (isA_CFDictionary(interface_entity
) == NULL
) {
3724 SCLog(TRUE
, LOG_DEBUG
, CFSTR("__SCNetworkInterfaceCreateWithStorageEntity: interface_entity is NULL or not of the correct type"));
3727 active
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceActive
));
3728 if (isA_CFBoolean(active
) == NULL
) {
3729 active
= kCFBooleanFalse
;
3731 bsdName
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceBSDName
));
3732 if (isA_CFString(bsdName
) == NULL
) {
3733 SCLog(TRUE
, LOG_DEBUG
, CFSTR("__SCNetworkInterfaceCreateWithStorageEntity: bsdName is NULL or not of the correct type"));
3736 ioBuiltin
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOBuiltin
));
3737 if (isA_CFBoolean(ioBuiltin
) == NULL
) {
3738 SCLog(TRUE
, LOG_DEBUG
, CFSTR("__SCNetworkInterfaceCreateWithStorageEntity: ioBuiltin is NULL or not of the correct type"));
3741 ioInterfaceNamePrefix
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceNamePrefix
));
3742 if (isA_CFString(ioInterfaceNamePrefix
) == NULL
) {
3743 ioInterfaceNamePrefix
= _SCNetworkInterfaceCopyPrefixFromBSDName(bsdName
);
3744 if (ioInterfaceNamePrefix
== NULL
) {
3745 SCLog(TRUE
, LOG_DEBUG
, CFSTR("__SCNetworkInterfaceCreateWithStorageEntity: ioInterfaceNamePrefix is NULL or not of the correct type"));
3750 CFRetain(ioInterfaceNamePrefix
);
3752 ioInterfaceType
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceType
));
3753 if (isA_CFNumber(ioInterfaceType
) == NULL
) {
3754 SCLog(TRUE
, LOG_DEBUG
, CFSTR("__SCNetworkInterfaceCreateWithStorageEntity: ioInterfaceType is NULL or not of the correct type"));
3757 if (CFNumberGetValue(ioInterfaceType
, kCFNumberIntType
, &ioInterfaceTypeNum
) == FALSE
) {
3758 SCLog(TRUE
, LOG_ERR
, CFSTR("__SCNetworkInterfaceCreateWithStorageEntity: Count not extract value from ioInterfaceType"));
3761 ioInterfaceUnit
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceUnit
));
3762 if (isA_CFNumber(ioInterfaceUnit
) == NULL
) {
3763 SCLog(TRUE
, LOG_DEBUG
, CFSTR("__SCNetworkInterfaceCreateWithStorageEntity: ioInterfaceUnit is NULL or not of the correct type"));
3767 ioMACAddress
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOMACAddress
));
3768 if (isA_CFData(ioMACAddress
) == NULL
) {
3769 SCLog(TRUE
, LOG_DEBUG
, CFSTR("__SCNetworkInterfaceCreateWithStorageEntity: ioMACAddress is NULL or not of the correct type"));
3772 ioPathMatch
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOPathMatch
));
3773 if (isA_CFString(ioPathMatch
) == NULL
) {
3774 SCLog(TRUE
, LOG_DEBUG
, CFSTR("__SCNetworkInterfaceCreateWithStorageEntity: ioPathMatch is NULL or not of the correct type"));
3778 // Check if Path contains the BSD Name in the end
3780 SCNetworkInterfaceInfo
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceInfo
));
3781 if (isA_CFDictionary(SCNetworkInterfaceInfo
) == NULL
) {
3782 SCLog(TRUE
, LOG_DEBUG
, CFSTR("__SCNetworkInterfaceCreateWithStorageEntity: SCNetworkInterfaceInfo is NULL or not of the correct type"));
3785 userDefinedName
= CFDictionaryGetValue(SCNetworkInterfaceInfo
, kSCPropUserDefinedName
);
3786 #if !TARGET_IPHONE_SIMULATOR
3787 usbProductName
= CFDictionaryGetValue(SCNetworkInterfaceInfo
, CFSTR(kUSBProductString
));
3788 idProduct
= CFDictionaryGetValue(SCNetworkInterfaceInfo
, CFSTR(kUSBProductID
));
3789 idVendor
= CFDictionaryGetValue(SCNetworkInterfaceInfo
, CFSTR(kUSBVendorID
));
3790 #endif // !TARGET_IPHONE_SIMULATOR
3792 type
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceType
));
3793 if (isA_CFString(type
) == NULL
) {
3794 SCLog(TRUE
, LOG_DEBUG
, CFSTR("__SCNetworkInterfaceCreateWithStorageEntity: type is NULL or not of the correct type"));
3798 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
);
3799 interfacePrivate
->active
= CFBooleanGetValue(active
);
3800 interfacePrivate
->entity_device
= CFRetain(bsdName
);
3801 interfacePrivate
->builtin
= CFBooleanGetValue(ioBuiltin
);
3802 interfacePrivate
->prefix
= CFRetain(ioInterfaceNamePrefix
);
3803 interfacePrivate
->type
= CFRetain(ioInterfaceType
);
3804 interfacePrivate
->unit
= CFRetain(ioInterfaceUnit
);
3805 interfacePrivate
->address
= CFRetain(ioMACAddress
);
3806 interfacePrivate
->path
= CFRetain(ioPathMatch
);
3807 interfacePrivate
->name
= ((userDefinedName
!= NULL
) ? CFRetain(userDefinedName
) : NULL
);
3808 interfacePrivate
->localized_name
= ((userDefinedName
!= NULL
) ? CFRetain(userDefinedName
) : NULL
);
3809 interfacePrivate
->usb
.name
= ((usbProductName
!= NULL
) ? CFRetain(usbProductName
) : NULL
);
3810 interfacePrivate
->usb
.pid
= ((idProduct
!= NULL
) ? CFRetain(idProduct
) : NULL
);
3811 interfacePrivate
->usb
.vid
= ((idVendor
!= NULL
) ? CFRetain(idVendor
) : NULL
);
3813 // Handling interface types to be seen in NetworkInterfaces.plist
3814 CFIndex interfaceIndex
;
3816 interfaceIndex
= findConfiguration(type
);
3817 if (interfaceIndex
!= kCFNotFound
) {
3818 interfacePrivate
->interface_type
= *configurations
[interfaceIndex
].interface_type
;
3821 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
3824 // Extracting entity type from value of interface type
3825 if (ioInterfaceTypeNum
== kInterfaceTypeEthernetValue
) {
3826 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
; // kSCNetworkInterfaceTypeEthernet;
3828 else if (ioInterfaceTypeNum
== kInterfaceTypeFirewireValue
) {
3829 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeFireWire
;
3832 if (ioInterfaceNamePrefix
!= NULL
) {
3833 CFRelease(ioInterfaceNamePrefix
);
3836 return (SCNetworkInterfaceRef
)interfacePrivate
;
3840 SCNetworkInterfaceRef
3841 _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef allocator
,
3842 CFDictionaryRef interface_entity
,
3843 SCNetworkServiceRef service
)
3845 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
3846 CFStringRef ifDevice
;
3847 CFStringRef ifName
= NULL
;
3848 CFStringRef ifSubType
;
3850 CFStringRef ifUnique
;
3851 CFArrayRef matching_interfaces
= NULL
;
3852 SCPreferencesRef servicePref
= NULL
;
3853 Boolean useSystemInterfaces
= TRUE
;
3855 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
3856 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
3858 if (service
!= NULL
) {
3859 servicePref
= ((SCNetworkServicePrivateRef
)service
)->prefs
;
3860 useSystemInterfaces
= ((__SCPreferencesUsingDefaultPrefs(servicePref
)) &&
3861 (__SCPreferencesGetLimitSCNetworkConfiguration(servicePref
) == FALSE
));
3864 ifType
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceType
);
3865 if (ifType
== NULL
) {
3867 * The interface "Type" was not specified. We'll make an
3868 * assumption that this is an "Ethernet" interface. If a
3869 * real interface exists with the provided interface name
3870 * then the actual type will be set accordingly. If not, we'll
3871 * end up crafting an "Ethernet" SCNetworkInterface that
3872 * will keep the rest of the configuration APIs happy.
3874 ifType
= kSCValNetInterfaceTypeEthernet
;
3877 if (!isA_CFString(ifType
)) {
3881 ifSubType
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceSubType
);
3882 if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) ||
3883 CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
3884 if (!isA_CFString(ifSubType
)) {
3889 ifDevice
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceDeviceName
);
3890 ifUnique
= CFDictionaryGetValue(interface_entity
, CFSTR("DeviceUniqueIdentifier"));
3892 if (CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
) ||
3893 CFEqual(ifType
, kSCValNetInterfaceTypeFireWire
) ||
3894 (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) && CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPoE
))) {
3895 char bsdName
[IFNAMSIZ
];
3896 CFMutableDictionaryRef matching
;
3898 if (!isA_CFString(ifDevice
)) {
3902 if (CFEqual(ifDevice
, CFSTR("lo0"))) { // for _SCNetworkInterfaceCreateWithBSDName
3903 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
3906 if (useSystemInterfaces
) {
3907 if (_SC_cfstring_to_cstring(ifDevice
, bsdName
, sizeof(bsdName
), kCFStringEncodingASCII
) == NULL
) {
3911 matching
= IOBSDNameMatching(masterPort
, 0, bsdName
);
3912 if (matching
== NULL
) {
3915 matching_interfaces
= findMatchingInterfaces(matching
, processNetworkInterface
, kSCNetworkInterfaceHiddenInterfaceKey
);
3916 CFRelease(matching
);
3918 } else if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
3919 if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPSerial
)) {
3920 CFDictionaryRef matching
;
3921 CFStringRef match_keys
[2];
3922 CFStringRef match_vals
[2];
3924 if (!isA_CFString(ifDevice
)) {
3928 if (useSystemInterfaces
) {
3929 match_keys
[0] = CFSTR(kIOProviderClassKey
);
3930 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
3932 match_keys
[1] = CFSTR(kIOTTYBaseNameKey
);
3933 match_vals
[1] = ifDevice
;
3935 matching
= CFDictionaryCreate(NULL
,
3936 (const void **)match_keys
,
3937 (const void **)match_vals
,
3938 sizeof(match_keys
)/sizeof(match_keys
[0]),
3939 &kCFTypeDictionaryKeyCallBacks
,
3940 &kCFTypeDictionaryValueCallBacks
);
3941 matching_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
, kSCNetworkInterfaceHiddenPortKey
);
3942 CFRelease(matching
);
3944 if (ifUnique
== NULL
) {
3946 Boolean useDeviceName
= TRUE
;
3948 n
= (matching_interfaces
!= NULL
) ? CFArrayGetCount(matching_interfaces
) : 0;
3952 for (i
= 0; i
< n
; i
++) {
3953 SCNetworkInterfacePrivateRef scanPrivate
;
3955 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
3956 if (scanPrivate
->entity_device_unique
!= NULL
) {
3957 useDeviceName
= FALSE
;
3963 if (useDeviceName
&& useSystemInterfaces
) {
3964 if (matching_interfaces
!= NULL
) {
3965 CFRelease(matching_interfaces
);
3968 match_keys
[1] = CFSTR(kIOTTYDeviceKey
);
3969 matching
= CFDictionaryCreate(NULL
,
3970 (const void **)match_keys
,
3971 (const void **)match_vals
,
3972 sizeof(match_keys
)/sizeof(match_keys
[0]),
3973 &kCFTypeDictionaryKeyCallBacks
,
3974 &kCFTypeDictionaryValueCallBacks
);
3975 matching_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
, kSCNetworkInterfaceHiddenPortKey
);
3976 CFRelease(matching
);
3979 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypeL2TP
)) {
3980 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
3981 kSCNetworkInterfaceTypeL2TP
);
3982 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPTP
)) {
3983 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
3984 kSCNetworkInterfaceTypePPTP
);
3986 // XXX do we allow non-Apple variants of PPP??? XXX
3987 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
3990 } else if (CFEqual(ifType
, kSCValNetInterfaceType6to4
)) {
3991 if (!isA_CFString(ifDevice
)) {
3995 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
3996 kSCNetworkInterfaceType6to4
);
3997 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeIPSec
)) {
3998 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
3999 kSCNetworkInterfaceTypeIPSec
);
4000 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeLoopback
)) {
4001 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
4002 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
4003 if (CFStringFind(ifSubType
, CFSTR("."), 0).location
!= kCFNotFound
) {
4004 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4007 } else if ((CFStringFind(ifType
, CFSTR("."), 0).location
!= kCFNotFound
) && (ifDevice
== NULL
)) {
4008 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4012 if (matching_interfaces
!= NULL
) {
4014 SCPreferencesRef prefs
;
4015 Boolean temp_preferences
= FALSE
;
4017 n
= CFArrayGetCount(matching_interfaces
);
4020 interfacePrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, 0);
4021 if (_SC_CFEqual(ifUnique
, interfacePrivate
->entity_device_unique
)) {
4022 // if the unique ID's match
4023 CFRetain(interfacePrivate
);
4027 interfacePrivate
= NULL
;
4030 if (!CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
)) {
4034 if (CFDictionaryGetValueIfPresent(interface_entity
,
4035 kSCPropUserDefinedName
,
4036 (const void **)&ifName
) &&
4037 CFEqual(ifName
, CFSTR(BT_PAN_NAME
))) {
4041 prefs
= (service
!= NULL
) ? ((SCNetworkServicePrivateRef
)service
)->prefs
: NULL
;
4042 if (prefs
== NULL
) {
4043 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), NULL
);
4044 if (prefs
!= NULL
) {
4045 temp_preferences
= TRUE
;
4048 if (prefs
== NULL
) {
4051 #if !TARGET_OS_IPHONE
4052 if (!CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_BOND_INTERFACES_"))) {
4053 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findBondInterface(prefs
, ifDevice
);
4055 #endif // !TARGET_OS_IPHONE
4056 if ((interfacePrivate
== NULL
)
4057 && !CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_BRIDGE_INTERFACES_"))) {
4058 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findBridgeInterface(prefs
, ifDevice
);
4061 if ((interfacePrivate
== NULL
)
4062 && !CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_VLAN_INTERFACES_"))) {
4063 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findVLANInterface(prefs
, ifDevice
);
4065 if (temp_preferences
) CFRelease(prefs
);
4068 if (ifUnique
!= NULL
) {
4071 // we are looking for an interface with a unique ID
4072 // so let's try to focus our choices
4073 for (i
= 0; i
< n
; i
++) {
4074 SCNetworkInterfacePrivateRef scanPrivate
;
4076 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
4077 if (_SC_CFEqual(ifUnique
, scanPrivate
->entity_device_unique
)) {
4078 if (interfacePrivate
!= NULL
) {
4079 // if we've matched more than one interface
4080 interfacePrivate
= NULL
;
4083 interfacePrivate
= scanPrivate
;
4086 } else if (CFDictionaryGetValueIfPresent(interface_entity
,
4087 kSCPropUserDefinedName
,
4088 (const void **)&ifName
)) {
4091 // we don't have a unique ID but do have an interface
4092 // name. If the matching interfaces do have IDs than
4093 // we can try to focus our choices using the name
4094 for (i
= 0; i
< n
; i
++) {
4095 SCNetworkInterfacePrivateRef scanPrivate
;
4097 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
4098 if (scanPrivate
->entity_device_unique
!= NULL
) {
4099 SCNetworkInterfaceRef scan
= (SCNetworkInterfaceRef
)scanPrivate
;
4100 CFStringRef scanName
;
4102 scanName
= __SCNetworkInterfaceGetNonLocalizedDisplayName(scan
);
4103 if ((scanName
!= NULL
) && !_SC_CFEqual(ifName
, scanName
)) {
4104 continue; // if not the same display name
4108 if (interfacePrivate
!= NULL
) {
4109 // if we've matched more than one interface
4110 interfacePrivate
= NULL
;
4113 interfacePrivate
= scanPrivate
;
4116 if (interfacePrivate
== NULL
) {
4117 SCLog(TRUE
, LOG_ERR
, CFSTR("_SCNetworkInterfaceCreateWithEntity() failed, more than one interface matches %@"), ifDevice
);
4118 interfacePrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, 0);
4120 CFRetain(interfacePrivate
);
4123 CFRelease(matching_interfaces
);
4128 if ((interfacePrivate
== NULL
) || (useSystemInterfaces
== FALSE
)) {
4130 * if device not present on this system
4132 if (useSystemInterfaces
== FALSE
) {
4133 if (interfacePrivate
!= NULL
) {
4134 CFRelease(interfacePrivate
);
4138 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
);
4139 interfacePrivate
->entity_type
= (ifType
!= NULL
) ? ifType
: NULL
;
4140 interfacePrivate
->entity_subtype
= (ifSubType
!= NULL
) ? ifSubType
: NULL
;
4141 interfacePrivate
->entity_device
= (ifDevice
!= NULL
) ? CFStringCreateCopy(NULL
, ifDevice
) : NULL
;
4142 interfacePrivate
->entity_device_unique
= (ifUnique
!= NULL
) ? CFStringCreateCopy(NULL
, ifUnique
) : NULL
;
4144 // Using UserDefinedName to check the validity of preferences file
4145 // when useSystemInterfaces is FALSE
4146 if (useSystemInterfaces
== FALSE
) {
4147 CFStringRef userDefinedName
= CFDictionaryGetValue(interface_entity
, kSCPropUserDefinedName
);
4148 if (isA_CFString(userDefinedName
) != NULL
) {
4149 CFRetain(userDefinedName
);
4150 if (interfacePrivate
->name
!= NULL
) {
4151 CFRelease(interfacePrivate
->name
);
4153 interfacePrivate
->name
= userDefinedName
;
4155 CFRetain(userDefinedName
);
4156 if (interfacePrivate
->localized_name
!= NULL
) {
4157 CFRelease(interfacePrivate
->localized_name
);
4159 interfacePrivate
->localized_name
= userDefinedName
;
4163 if (CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
)) {
4164 CFStringRef entity_hardware
;
4165 SCNetworkInterfaceRef virtualInterface
;
4167 if ((useSystemInterfaces
== FALSE
) &&
4168 (((virtualInterface
= findBridgeInterface(servicePref
, ifDevice
)) != NULL
) ||
4169 #if !TARGET_OS_IPHONE
4170 ((virtualInterface
= findBondInterface(servicePref
, ifDevice
)) != NULL
) ||
4172 ((virtualInterface
= findVLANInterface(servicePref
, ifDevice
)) != NULL
))) {
4173 CFRelease(interfacePrivate
);
4174 interfacePrivate
= (SCNetworkInterfacePrivateRef
)virtualInterface
;
4176 entity_hardware
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceHardware
);
4177 if (isA_CFString((entity_hardware
)) &&
4178 CFEqual(entity_hardware
, kSCEntNetAirPort
)) {
4179 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
4180 interfacePrivate
->localized_key
= CFSTR("airport");
4181 interfacePrivate
->sort_order
= kSortAirPort
;
4185 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
4187 name
= CFDictionaryGetValue(interface_entity
, kSCPropUserDefinedName
);
4188 if (__SCNetworkInterfaceMatchesName(name
, CFSTR("iPhone"))) {
4189 interfacePrivate
->localized_key
= CFSTR("iPhone");
4190 interfacePrivate
->sort_order
= kSortTethered
;
4191 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("iPad"))) {
4192 interfacePrivate
->localized_key
= CFSTR("iPad");
4193 interfacePrivate
->sort_order
= kSortTethered
;
4194 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("thunderbolt"))) {
4195 interfacePrivate
->localized_key
= CFSTR("thunderbolt");
4196 interfacePrivate
->sort_order
= kSortThunderbolt
;
4197 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-gn"))) {
4198 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-gn");
4199 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
4200 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-nap"))) {
4201 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-nap");
4202 interfacePrivate
->sort_order
= kSortBluetoothPAN_NAP
;
4203 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-u"))) {
4204 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-u");
4205 interfacePrivate
->sort_order
= kSortBluetoothPAN_U
;
4207 interfacePrivate
->sort_order
= kSortEthernet
;
4211 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeFireWire
)) {
4212 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeFireWire
;
4213 interfacePrivate
->sort_order
= kSortFireWire
;
4214 } else if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
4215 if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPoE
)) {
4216 CFStringRef entity_hardware
;
4218 entity_hardware
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceHardware
);
4219 if (isA_CFString((entity_hardware
)) &&
4220 CFEqual(entity_hardware
, kSCEntNetAirPort
)) {
4221 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
4222 interfacePrivate
->sort_order
= kSortAirPort
;
4224 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
4225 interfacePrivate
->sort_order
= kSortEthernet
;
4227 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPSerial
)) {
4228 if (CFStringHasPrefix(ifDevice
, CFSTR("Bluetooth"))) {
4229 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBluetooth
;
4230 interfacePrivate
->sort_order
= kSortBluetooth
;
4231 } else if (CFStringHasPrefix(ifDevice
, CFSTR("irda"))) {
4232 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIrDA
;
4233 interfacePrivate
->sort_order
= kSortIrDA
;
4234 } else if (CFStringHasPrefix(ifDevice
, CFSTR("wwan"))) {
4235 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeWWAN
;
4236 interfacePrivate
->sort_order
= kSortWWAN
;
4238 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeModem
;
4239 interfacePrivate
->sort_order
= kSortModem
;
4242 SCNetworkInterfaceRef child
;
4244 CFRelease(interfacePrivate
);
4245 child
= SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
, ifSubType
);
4246 interfacePrivate
= (SCNetworkInterfacePrivateRef
)child
;
4247 if (interfacePrivate
== NULL
) {
4251 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
4252 SCNetworkInterfaceRef child
;
4253 CFRelease(interfacePrivate
);
4254 child
= SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
, ifSubType
);
4255 interfacePrivate
= (SCNetworkInterfacePrivateRef
)child
;
4256 if (interfacePrivate
== NULL
) {
4259 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeIPSec
)) {
4260 CFRelease(interfacePrivate
);
4261 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4262 kSCNetworkInterfaceTypeIPSec
);
4263 } else if (CFEqual(ifType
, kSCValNetInterfaceType6to4
)) {
4264 CFRelease(interfacePrivate
);
4265 if (!isA_CFString(ifDevice
)) {
4268 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4269 kSCNetworkInterfaceType6to4
);
4270 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeLoopback
)) {
4271 CFRelease(interfacePrivate
);
4272 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
4273 } else if (CFStringFind(ifType
, CFSTR("."), 0).location
!= kCFNotFound
) {
4274 // if vendor interface
4275 if (vendor_interface_types
== NULL
) {
4276 vendor_interface_types
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
4278 CFSetAddValue(vendor_interface_types
, ifType
);
4280 interfacePrivate
->interface_type
= CFSetGetValue(vendor_interface_types
, ifType
);
4282 // if unknown interface
4283 CFRelease(interfacePrivate
);
4284 interfacePrivate
= NULL
;
4288 if (CFDictionaryContainsKey(interface_entity
, kSCNetworkInterfaceHiddenConfigurationKey
)) {
4289 interfacePrivate
->hidden
= TRUE
;
4293 if (service
!= NULL
) {
4294 __SCNetworkInterfaceSetService((SCNetworkInterfaceRef
)interfacePrivate
,
4297 #if !TARGET_OS_IPHONE
4298 // set prefs & serviceID to Bond member interfaces
4299 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBond
)) {
4304 members
= SCBondInterfaceGetMemberInterfaces((SCNetworkInterfaceRef
)interfacePrivate
);
4305 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
4306 for (i
= 0; i
< n
; i
++) {
4307 SCNetworkInterfaceRef member
;
4309 member
= CFArrayGetValueAtIndex(members
, i
);
4310 __SCNetworkInterfaceSetService(member
, service
);
4313 #endif // !TARGET_OS_IPHONE
4315 // set prefs & serviceID to Bridge member interfaces
4316 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBridge
)) {
4321 members
= SCBridgeInterfaceGetMemberInterfaces((SCNetworkInterfaceRef
)interfacePrivate
);
4322 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
4323 for (i
= 0; i
< n
; i
++) {
4324 SCNetworkInterfaceRef member
;
4326 member
= CFArrayGetValueAtIndex(members
, i
);
4327 __SCNetworkInterfaceSetService(member
, service
);
4330 // set prefs & serviceID to VLAN pyhsical interface
4331 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeVLAN
)) {
4332 SCNetworkInterfaceRef vlan_physical
;
4334 vlan_physical
= SCVLANInterfaceGetPhysicalInterface((SCNetworkInterfaceRef
)interfacePrivate
);
4335 if (vlan_physical
!= NULL
) {
4336 __SCNetworkInterfaceSetService(vlan_physical
, service
);
4341 if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
4342 SCNetworkInterfaceRef parent
;
4345 parent
= SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef
)interfacePrivate
,
4346 kSCNetworkInterfaceTypePPP
);
4347 CFRelease(interfacePrivate
);
4348 interfacePrivate
= (SCNetworkInterfacePrivateRef
)parent
;
4349 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
4350 SCNetworkInterfaceRef parent
;
4353 parent
= SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef
)interfacePrivate
,
4354 kSCNetworkInterfaceTypeVPN
);
4355 CFRelease(interfacePrivate
);
4356 interfacePrivate
= (SCNetworkInterfacePrivateRef
)parent
;
4359 return (SCNetworkInterfaceRef
)interfacePrivate
;
4364 #pragma mark SCNetworkInterface APIs
4369 __SCNetworkInterfaceCopyAll_IONetworkInterface(void)
4371 CFDictionaryRef matching
;
4372 CFArrayRef new_interfaces
;
4374 // get Ethernet, Firewire, Thunderbolt, and AirPort interfaces
4376 matching
= IOServiceMatching(kIONetworkInterfaceClass
);
4377 new_interfaces
= findMatchingInterfaces(matching
, processNetworkInterface
, kSCNetworkInterfaceHiddenInterfaceKey
);
4378 CFRelease(matching
);
4380 return new_interfaces
;
4386 __SCNetworkInterfaceCopyAll_Modem()
4388 CFDictionaryRef matching
;
4389 CFStringRef match_keys
[2];
4390 CFStringRef match_vals
[2];
4391 CFArrayRef new_interfaces
;
4393 match_keys
[0] = CFSTR(kIOProviderClassKey
);
4394 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
4396 match_keys
[1] = CFSTR(kIOSerialBSDTypeKey
);
4397 match_vals
[1] = CFSTR(kIOSerialBSDModemType
);
4399 matching
= CFDictionaryCreate(NULL
,
4400 (const void **)match_keys
,
4401 (const void **)match_vals
,
4402 sizeof(match_keys
)/sizeof(match_keys
[0]),
4403 &kCFTypeDictionaryKeyCallBacks
,
4404 &kCFTypeDictionaryValueCallBacks
);
4405 new_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
, kSCNetworkInterfaceHiddenPortKey
);
4406 CFRelease(matching
);
4408 return new_interfaces
;
4414 __SCNetworkInterfaceCopyAll_RS232()
4416 CFDictionaryRef matching
;
4417 CFStringRef match_keys
[2];
4418 CFStringRef match_vals
[2];
4419 CFArrayRef new_interfaces
;
4421 match_keys
[0] = CFSTR(kIOProviderClassKey
);
4422 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
4424 match_keys
[1] = CFSTR(kIOSerialBSDTypeKey
);
4425 match_vals
[1] = CFSTR(kIOSerialBSDRS232Type
);
4427 matching
= CFDictionaryCreate(NULL
,
4428 (const void **)match_keys
,
4429 (const void **)match_vals
,
4430 sizeof(match_keys
)/sizeof(match_keys
[0]),
4431 &kCFTypeDictionaryKeyCallBacks
,
4432 &kCFTypeDictionaryValueCallBacks
);
4433 new_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
, kSCNetworkInterfaceHiddenPortKey
);
4434 CFRelease(matching
);
4436 return new_interfaces
;
4440 #if !TARGET_OS_IPHONE
4442 addBTPANInterface(SCPreferencesRef prefs
, CFMutableArrayRef all_interfaces
)
4445 SCNetworkInterfaceRef interface
;
4448 n
= CFArrayGetCount(all_interfaces
);
4449 for (i
= 0; i
< n
; i
++) {
4450 SCNetworkInterfaceRef interface
;
4452 interface
= CFArrayGetValueAtIndex(all_interfaces
, i
);
4453 if (_SCNetworkInterfaceIsBluetoothPAN(interface
)) {
4454 // if we already have a BT-PAN interface
4459 interface
= _SCNetworkInterfaceCopyBTPANInterface();
4460 if (interface
!= NULL
) {
4461 // include BT-PAN interface
4462 CFArrayAppendValue(all_interfaces
, interface
);
4463 CFRelease(interface
);
4468 #endif // !TARGET_OS_IPHONE
4472 add_interfaces(CFMutableArrayRef all_interfaces
, CFArrayRef new_interfaces
)
4477 n
= CFArrayGetCount(new_interfaces
);
4478 for (i
= 0; i
< n
; i
++) {
4479 CFStringRef bsdName
;
4480 SCNetworkInterfaceRef interface
;
4482 interface
= CFArrayGetValueAtIndex(new_interfaces
, i
);
4483 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
4484 if (bsdName
!= NULL
) {
4485 CFArrayAppendValue(all_interfaces
, interface
);
4494 __waitForInterfaces()
4499 SCDynamicStoreRef store
;
4501 store
= SCDynamicStoreCreate(NULL
, CFSTR("SCNetworkInterfaceCopyAll"), NULL
, NULL
);
4502 if (store
== NULL
) {
4506 key
= SCDynamicStoreKeyCreate(NULL
, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin
);
4507 keys
= CFArrayCreate(NULL
, (const void **)&key
, 1, &kCFTypeArrayCallBacks
);
4508 ok
= SCDynamicStoreSetNotificationKeys(store
, keys
, NULL
);
4511 SCLog(TRUE
, LOG_ERR
,
4512 CFSTR("SCDynamicStoreSetNotificationKeys() failed: %s"), SCErrorString(SCError()));
4517 CFArrayRef changedKeys
;
4518 CFDictionaryRef dict
;
4519 Boolean quiet
= FALSE
;
4522 dict
= SCDynamicStoreCopyValue(store
, key
);
4524 if (isA_CFDictionary(dict
) &&
4525 (CFDictionaryContainsKey(dict
, CFSTR("*QUIET*")) ||
4526 CFDictionaryContainsKey(dict
, CFSTR("*TIMEOUT*")))) {
4535 ok
= SCDynamicStoreNotifyWait(store
);
4537 SCLog(TRUE
, LOG_ERR
,
4538 CFSTR("SCDynamicStoreNotifyWait() failed: %s"), SCErrorString(SCError()));
4542 changedKeys
= SCDynamicStoreCopyNotifiedKeys(store
);
4543 if (changedKeys
!= NULL
) {
4544 CFRelease(changedKeys
);
4556 CFArrayRef
/* of SCNetworkInterfaceRef's */
4557 _SCNetworkInterfaceCopyAllWithPreferences(SCPreferencesRef prefs
)
4559 CFMutableArrayRef all_interfaces
;
4560 CFArrayRef new_interfaces
;
4561 Boolean temp_preferences
= FALSE
;
4563 /* initialize runtime */
4564 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4566 /* wait for IOKit to quiesce */
4567 pthread_once(&iokit_quiet
, __waitForInterfaces
);
4569 all_interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4571 // get Ethernet, Firewire, Thunderbolt, and AirPort interfaces
4572 new_interfaces
= __SCNetworkInterfaceCopyAll_IONetworkInterface();
4573 if (new_interfaces
!= NULL
) {
4574 add_interfaces(all_interfaces
, new_interfaces
);
4575 CFRelease(new_interfaces
);
4578 // get Modem interfaces
4579 new_interfaces
= __SCNetworkInterfaceCopyAll_Modem();
4580 if (new_interfaces
!= NULL
) {
4581 add_interfaces(all_interfaces
, new_interfaces
);
4582 CFRelease(new_interfaces
);
4585 // get serial (RS232) interfaces
4586 new_interfaces
= __SCNetworkInterfaceCopyAll_RS232();
4587 if (new_interfaces
!= NULL
) {
4588 add_interfaces(all_interfaces
, new_interfaces
);
4589 CFRelease(new_interfaces
);
4592 // get virtual network interfaces (Bond, Bridge, VLAN)
4593 if (prefs
== NULL
) {
4594 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterfaceCopyAll"), NULL
);
4595 if (prefs
!= NULL
) {
4596 temp_preferences
= TRUE
;
4599 if (prefs
!= NULL
) {
4600 #if !TARGET_OS_IPHONE
4601 new_interfaces
= SCBondInterfaceCopyAll(prefs
);
4602 if (new_interfaces
!= NULL
) {
4603 add_interfaces(all_interfaces
, new_interfaces
);
4604 CFRelease(new_interfaces
);
4606 #endif // !TARGET_OS_IPHONE
4608 new_interfaces
= SCBridgeInterfaceCopyAll(prefs
);
4609 if (new_interfaces
!= NULL
) {
4610 add_interfaces(all_interfaces
, new_interfaces
);
4611 CFRelease(new_interfaces
);
4614 new_interfaces
= SCVLANInterfaceCopyAll(prefs
);
4615 if (new_interfaces
!= NULL
) {
4616 add_interfaces(all_interfaces
, new_interfaces
);
4617 CFRelease(new_interfaces
);
4620 #if !TARGET_OS_IPHONE
4621 // add BT-PAN interface
4622 addBTPANInterface(prefs
, all_interfaces
);
4623 #endif // !TARGET_OS_IPHONE
4625 if (temp_preferences
) CFRelease(prefs
);
4628 // all interfaces have been identified, order and return
4629 sort_interfaces(all_interfaces
);
4631 return all_interfaces
;
4635 CFArrayRef
/* of SCNetworkInterfaceRef's */
4636 SCNetworkInterfaceCopyAll()
4638 CFArrayRef all_interfaces
;
4640 all_interfaces
= _SCNetworkInterfaceCopyAllWithPreferences(NULL
);
4641 return all_interfaces
;
4645 CFArrayRef
/* of kSCNetworkInterfaceTypeXXX CFStringRef's */
4646 SCNetworkInterfaceGetSupportedInterfaceTypes(SCNetworkInterfaceRef interface
)
4649 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4651 if (!isA_SCNetworkInterface(interface
)) {
4652 _SCErrorSet(kSCStatusInvalidArgument
);
4656 if (interfacePrivate
->supported_interface_types
!= NULL
) {
4660 i
= findConfiguration(interfacePrivate
->interface_type
);
4661 if (i
!= kCFNotFound
) {
4662 if (configurations
[i
].supported_interfaces
!= doNone
) {
4663 interfacePrivate
->supported_interface_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4664 if (configurations
[i
].supported_interfaces
& do6to4
) {
4665 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceType6to4
);
4667 if (configurations
[i
].supported_interfaces
& doL2TP
) {
4668 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeL2TP
);
4670 if (configurations
[i
].supported_interfaces
& doPPP
) {
4671 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypePPP
);
4673 if (configurations
[i
].supported_interfaces
& doPPTP
) {
4674 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypePPTP
);
4676 if (configurations
[i
].supported_interfaces
& doIPSec
) {
4677 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeIPSec
);
4681 SCNetworkInterfaceRef child
;
4683 child
= SCNetworkInterfaceGetInterface(interface
);
4684 if ((child
!= NULL
) && CFEqual(child
, kSCNetworkInterfaceIPv4
)) {
4685 interfacePrivate
->supported_interface_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4686 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeVPN
);
4692 return interfacePrivate
->supported_interface_types
;
4696 CFArrayRef
/* of kSCNetworkProtocolTypeXXX CFStringRef's */
4697 SCNetworkInterfaceGetSupportedProtocolTypes(SCNetworkInterfaceRef interface
)
4700 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4702 if (!isA_SCNetworkInterface(interface
)) {
4703 _SCErrorSet(kSCStatusInvalidArgument
);
4707 if (interfacePrivate
->supported_protocol_types
!= NULL
) {
4711 i
= findConfiguration(interfacePrivate
->interface_type
);
4712 if (i
!= kCFNotFound
) {
4713 if (configurations
[i
].supported_protocols
!= doNone
) {
4714 interfacePrivate
->supported_protocol_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4715 if (configurations
[i
].supported_protocols
& doDNS
) {
4716 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeDNS
);
4718 if (configurations
[i
].supported_protocols
& doIPv4
) {
4719 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeIPv4
);
4721 if (configurations
[i
].supported_protocols
& doIPv6
) {
4722 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeIPv6
);
4724 if (configurations
[i
].supported_protocols
& doProxies
) {
4725 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeProxies
);
4727 #if !TARGET_OS_IPHONE
4728 if (configurations
[i
].supported_protocols
& doSMB
) {
4729 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeSMB
);
4731 #endif // !TARGET_OS_IPHONE
4737 return interfacePrivate
->supported_protocol_types
;
4741 SCNetworkInterfaceRef
4742 SCNetworkInterfaceCreateWithInterface(SCNetworkInterfaceRef child
, CFStringRef interfaceType
)
4744 SCNetworkInterfacePrivateRef childPrivate
= (SCNetworkInterfacePrivateRef
)child
;
4746 SCNetworkInterfacePrivateRef parentPrivate
;
4748 if (!isA_SCNetworkInterface(child
)) {
4749 _SCErrorSet(kSCStatusInvalidArgument
);
4753 if (!isA_CFString(interfaceType
)) {
4754 _SCErrorSet(kSCStatusInvalidArgument
);
4758 if (CFEqual(child
, kSCNetworkInterfaceLoopback
)) {
4759 // can't layer on top of loopback
4760 _SCErrorSet(kSCStatusInvalidArgument
);
4764 childIndex
= findConfiguration(childPrivate
->interface_type
);
4766 parentPrivate
= __SCNetworkInterfaceCreatePrivate(NULL
,
4768 childPrivate
->prefs
,
4769 childPrivate
->serviceID
);
4770 if (parentPrivate
== NULL
) {
4771 _SCErrorSet(kSCStatusFailed
);
4775 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
4776 parentPrivate
->interface_type
= kSCNetworkInterfaceTypePPP
;
4777 parentPrivate
->entity_type
= kSCValNetInterfaceTypePPP
;
4780 if (childIndex
!= kCFNotFound
) {
4781 if (configurations
[childIndex
].ppp_subtype
!= NULL
) {
4782 parentPrivate
->entity_subtype
= *configurations
[childIndex
].ppp_subtype
;
4784 // sorry, the child interface does not support PPP
4788 // if the child's interface type not known, use the child entities "Type"
4789 parentPrivate
->entity_subtype
= childPrivate
->entity_type
;
4792 if (childPrivate
->entity_device
!= NULL
) {
4793 parentPrivate
->entity_device
= CFStringCreateCopy(NULL
, childPrivate
->entity_device
);
4796 if (childPrivate
->entity_device_unique
!= NULL
) {
4797 parentPrivate
->entity_device_unique
= CFStringCreateCopy(NULL
, childPrivate
->entity_device_unique
);
4799 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
4800 if ((childIndex
== kCFNotFound
) ||
4801 ((configurations
[childIndex
].supported_interfaces
& doL2TP
) != doL2TP
)) {
4802 // if the child interface does not support L2TP
4805 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeL2TP
;
4806 parentPrivate
->localized_key
= CFSTR("l2tp");
4807 parentPrivate
->entity_type
= kSCEntNetL2TP
; // interface config goes into "L2TP"
4808 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPTP
)) {
4809 if ((childIndex
== kCFNotFound
) ||
4810 ((configurations
[childIndex
].supported_interfaces
& doPPTP
) != doPPTP
)) {
4811 // if the child interface does not support PPTP
4814 parentPrivate
->interface_type
= kSCNetworkInterfaceTypePPTP
;
4815 parentPrivate
->localized_key
= CFSTR("pptp");
4816 parentPrivate
->entity_type
= kSCEntNetPPTP
; // interface config goes into "PPTP"
4817 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceType6to4
)) {
4818 if ((childIndex
== kCFNotFound
) ||
4819 ((configurations
[childIndex
].supported_interfaces
& do6to4
) != do6to4
)) {
4820 // if the child interface does not support 6to4
4824 parentPrivate
->interface_type
= kSCNetworkInterfaceType6to4
;
4825 parentPrivate
->localized_key
= CFSTR("6to4");
4826 parentPrivate
->entity_type
= kSCValNetInterfaceType6to4
;
4827 parentPrivate
->entity_device
= CFRetain(CFSTR("stf0"));
4828 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
4829 if ((childIndex
== kCFNotFound
) ||
4830 ((configurations
[childIndex
].supported_interfaces
& doIPSec
) != doIPSec
)) {
4831 // if the child interface does not support IPSec
4834 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeIPSec
;
4835 parentPrivate
->localized_key
= CFSTR("ipsec");
4836 parentPrivate
->entity_type
= kSCValNetInterfaceTypeIPSec
;
4837 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) {
4838 if (childIndex
!= kCFNotFound
) {
4839 // if not a "vendor" child interface
4843 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeVPN
;
4844 parentPrivate
->localized_key
= CFSTR("vpn");
4845 parentPrivate
->localized_arg1
= CFRetain(childPrivate
->entity_type
);
4846 parentPrivate
->entity_type
= kSCValNetInterfaceTypeVPN
;
4847 parentPrivate
->entity_subtype
= childPrivate
->entity_type
;
4848 if (childPrivate
->entity_device
!= NULL
) {
4849 parentPrivate
->entity_device
= CFStringCreateCopy(NULL
, childPrivate
->entity_device
);
4851 if (parentPrivate
->entity_subtype
!= NULL
) {
4852 CFArrayRef components
;
4854 CFStringRef vpnType
;
4857 // the "default" interface name is derived from the VPN type
4860 // com.apple.Apple-VPN.vpnplugin --> "Apple VPN"
4863 vpnType
= parentPrivate
->entity_subtype
;
4864 components
= CFStringCreateArrayBySeparatingStrings(NULL
, vpnType
, CFSTR("."));
4865 n
= CFArrayGetCount(components
);
4867 CFEqual(CFArrayGetValueAtIndex(components
, n
- 1), CFSTR("vpnplugin"))) {
4868 CFMutableStringRef str
;
4870 str
= CFStringCreateMutableCopy(NULL
,
4872 CFArrayGetValueAtIndex(components
, n
- 2));
4873 (void) CFStringFindAndReplace(str
,
4876 CFRangeMake(0, CFStringGetLength(str
)),
4878 parentPrivate
->localized_name
= str
;
4880 CFRelease(components
);
4882 } else if (CFStringFind(interfaceType
, CFSTR("."), 0).location
!= kCFNotFound
) {
4883 // if custom interface type
4884 if (vendor_interface_types
== NULL
) {
4885 vendor_interface_types
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
4887 CFSetAddValue(vendor_interface_types
, interfaceType
);
4889 parentPrivate
->interface_type
= CFSetGetValue(vendor_interface_types
, interfaceType
);
4890 parentPrivate
->entity_type
= parentPrivate
->interface_type
; // interface config goes into a
4891 // a dictionary with the same
4892 // name as the interfaceType
4894 // unknown interface type
4898 parentPrivate
->hidden
= childPrivate
->hidden
;
4900 if (childPrivate
->overrides
!= NULL
) {
4901 parentPrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, childPrivate
->overrides
);
4904 // The following change handles the case where a user has both an Ethernet and
4905 // PPPoE network service. Because a PPPoE service is typically associated with
4906 // an ISP we want it to be sorted higher in the service order.
4907 if ((parentPrivate
->entity_subtype
!= NULL
) &&
4908 (CFEqual(parentPrivate
->entity_subtype
, kSCValNetInterfaceSubTypePPPoE
))) {
4909 if ((childPrivate
->interface_type
!= NULL
) &&
4910 (CFEqual(childPrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
))) {
4911 parentPrivate
->sort_order
= kSortAirportPPP
;
4913 parentPrivate
->sort_order
= kSortEthernetPPP
;
4916 // set sort order of the parent to match the child interface
4917 parentPrivate
->sort_order
= childPrivate
->sort_order
;
4920 return (SCNetworkInterfaceRef
)parentPrivate
;
4924 CFRelease(parentPrivate
);
4925 _SCErrorSet(kSCStatusInvalidArgument
);
4932 __SCNetworkInterfaceGetDefaultConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
)
4934 CFDictionaryRef config
= NULL
;
4935 CFStringRef defaultType
;
4936 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4938 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
4939 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4941 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
4942 if (defaultType
!= NULL
) {
4946 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
4947 SCNetworkSetGetSetID(set
), // set
4948 interfacePrivate
->entity_device
, // interface
4949 defaultType
); // entity
4951 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
4954 if (config
== NULL
) {
4955 // if the "set" does not have a saved configuration, use
4956 // the [template] "interface" configuration
4957 if (interfacePrivate
->unsaved
!= NULL
) {
4958 config
= CFDictionaryGetValue(interfacePrivate
->unsaved
, defaultType
);
4959 if (config
== (CFDictionaryRef
)kCFNull
) {
4964 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
4975 static CFDictionaryRef
4976 __SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface
,
4977 CFStringRef extendedType
)
4979 CFDictionaryRef config
= NULL
;
4980 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4983 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
4984 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4986 paths
= copyConfigurationPaths(interfacePrivate
, extendedType
);
4987 if (paths
!= NULL
) {
4990 path
= CFArrayGetValueAtIndex(paths
, 0);
4991 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
4995 if (interfacePrivate
->unsaved
!= NULL
) {
4996 config
= CFDictionaryGetValue(interfacePrivate
->unsaved
, extendedType
);
4997 if (config
== (CFDictionaryRef
)kCFNull
) {
5003 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5012 SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface
)
5014 CFDictionaryRef config
;
5015 CFStringRef defaultType
;
5017 if (!isA_SCNetworkInterface(interface
)) {
5018 _SCErrorSet(kSCStatusInvalidArgument
);
5022 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5023 if (defaultType
== NULL
) {
5027 config
= __SCNetworkInterfaceGetConfiguration(interface
, defaultType
);
5028 if (config
== NULL
) {
5029 if (CFEqual(defaultType
, kSCEntNetAirPort
)) {
5030 SCNetworkInterfacePrivateRef interfacePrivate
;
5033 // if AirPort interface, check for a per-service config
5034 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5035 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
5036 interfacePrivate
->serviceID
, // service
5037 kSCEntNetAirPort
); // entity
5038 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
5042 if (config
== NULL
) {
5043 _SCErrorSet(kSCStatusOK
);
5051 SCNetworkInterfaceGetExtendedConfiguration(SCNetworkInterfaceRef interface
,
5052 CFStringRef extendedType
)
5054 CFDictionaryRef config
;
5056 if (!isA_SCNetworkInterface(interface
)) {
5057 _SCErrorSet(kSCStatusInvalidArgument
);
5061 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, TRUE
)) {
5062 _SCErrorSet(kSCStatusInvalidArgument
);
5066 config
= __SCNetworkInterfaceGetConfiguration(interface
, extendedType
);
5067 if (config
== NULL
) {
5068 _SCErrorSet(kSCStatusOK
);
5077 __SCNetworkInterfaceGetEntityType(SCNetworkInterfaceRef interface
)
5079 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5081 return interfacePrivate
->entity_type
;
5087 __SCNetworkInterfaceGetEntitySubType(SCNetworkInterfaceRef interface
)
5089 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
) interface
;
5091 return interfacePrivate
->entity_subtype
;
5096 SCNetworkInterfaceGetBSDName(SCNetworkInterfaceRef interface
)
5098 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5100 if (!isA_SCNetworkInterface(interface
)) {
5101 _SCErrorSet(kSCStatusInvalidArgument
);
5105 if ((interfacePrivate
->interface
!= NULL
) &&
5106 (interfacePrivate
->interface
!= kSCNetworkInterfaceIPv4
)) {
5107 _SCErrorSet(kSCStatusOK
);
5111 return interfacePrivate
->entity_device
;
5116 SCNetworkInterfaceGetHardwareAddressString(SCNetworkInterfaceRef interface
)
5118 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5120 if (!isA_SCNetworkInterface(interface
)) {
5121 _SCErrorSet(kSCStatusInvalidArgument
);
5125 if ((interfacePrivate
->address
!= NULL
) &&
5126 (interfacePrivate
->addressString
== NULL
)) {
5130 char mac
[sizeof("xx:xx:xx:xx:xx:xx:xx:xx")];
5133 bp
= (uint8_t *)CFDataGetBytePtr(interfacePrivate
->address
);
5134 n
= CFDataGetLength(interfacePrivate
->address
) * 3;
5136 if (n
> sizeof(mac
)) {
5137 mac_p
= CFAllocatorAllocate(NULL
, 0, n
);
5140 for (cp
= mac_p
; n
> 0; n
-= 3) {
5141 cp
+= snprintf(cp
, n
, "%2.2x:", *bp
++);
5144 interfacePrivate
->addressString
= CFStringCreateWithCString(NULL
, mac_p
, kCFStringEncodingUTF8
);
5145 if (mac_p
!= mac
) CFAllocatorDeallocate(NULL
, mac_p
);
5148 return interfacePrivate
->addressString
;
5152 SCNetworkInterfaceRef
5153 SCNetworkInterfaceGetInterface(SCNetworkInterfaceRef interface
)
5155 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5157 if (!isA_SCNetworkInterface(interface
)) {
5158 _SCErrorSet(kSCStatusInvalidArgument
);
5162 return interfacePrivate
->interface
;
5167 SCNetworkInterfaceGetInterfaceType(SCNetworkInterfaceRef interface
)
5169 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5171 if (!isA_SCNetworkInterface(interface
)) {
5172 _SCErrorSet(kSCStatusInvalidArgument
);
5176 return interfacePrivate
->interface_type
;
5181 copy_interface_string(CFBundleRef bundle
, CFStringRef key
, Boolean localized
)
5183 CFStringRef str
= NULL
;
5186 str
= CFBundleCopyLocalizedString(bundle
,
5189 NETWORKINTERFACE_LOCALIZATIONS
);
5191 str
= _SC_CFBundleCopyNonLocalizedString(bundle
,
5194 NETWORKINTERFACE_LOCALIZATIONS
);
5202 copy_display_name(SCNetworkInterfaceRef interface
, Boolean localized
, Boolean oldLocalization
)
5204 CFMutableStringRef local
;
5207 local
= CFStringCreateMutable(NULL
, 0);
5209 while (interface
!= NULL
) {
5210 Boolean added
= FALSE
;
5211 SCNetworkInterfaceRef child
= NULL
;
5212 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5214 if ((interfacePrivate
->interface
!= NULL
) &&
5215 (interfacePrivate
->interface
!= kSCNetworkInterfaceIPv4
) &&
5216 !CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeVPN
)) {
5217 child
= interfacePrivate
->interface
;
5220 if ((bundle
!= NULL
) && (interfacePrivate
->localized_key
!= NULL
)) {
5222 CFStringRef key
= interfacePrivate
->localized_key
;
5224 if (oldLocalization
) {
5225 key
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("X-%@"),
5226 interfacePrivate
->localized_key
);
5228 fmt
= copy_interface_string(bundle
, key
, localized
);
5230 CFStringAppendFormat(local
,
5233 interfacePrivate
->localized_arg1
,
5234 interfacePrivate
->localized_arg2
);
5238 if (oldLocalization
) {
5244 (interfacePrivate
->prefs
!= NULL
) &&
5245 (interfacePrivate
->serviceID
!= NULL
) &&
5247 CFDictionaryRef entity
;
5250 // check for (and use) the name of the interface when it
5251 // was last available
5252 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,
5253 interfacePrivate
->serviceID
,
5254 kSCEntNetInterface
);
5255 entity
= SCPreferencesPathGetValue(interfacePrivate
->prefs
, path
);
5257 if (isA_CFDictionary(entity
)) {
5260 name
= CFDictionaryGetValue(entity
, kSCPropUserDefinedName
);
5261 if (isA_CFString(name
)) {
5262 CFStringAppend(local
, name
);
5269 // create (non-)localized name based on the interface type
5270 CFStringAppend(local
, interfacePrivate
->interface_type
);
5272 // ... and, if this is a leaf node, the interface device
5273 if ((interfacePrivate
->entity_device
!= NULL
) && (child
== NULL
)) {
5274 CFStringAppendFormat(local
, NULL
, CFSTR(" (%@)"), interfacePrivate
->entity_device
);
5278 if (child
!= NULL
) {
5279 // if this interface is layered over another
5280 CFStringAppend(local
, CFSTR(" --> "));
5286 name
= CFStringCreateCopy(NULL
, local
);
5293 #if !TARGET_OS_IPHONE
5296 __SCNetworkInterfaceCopyXLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5300 if (!isA_SCNetworkInterface(interface
)) {
5301 _SCErrorSet(kSCStatusInvalidArgument
);
5305 name
= copy_display_name(interface
, TRUE
, TRUE
);
5312 __SCNetworkInterfaceCopyXNonLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5314 CFStringRef localized_name
;
5316 if (!isA_SCNetworkInterface(interface
)) {
5317 _SCErrorSet(kSCStatusInvalidArgument
);
5321 localized_name
= copy_display_name(interface
, FALSE
, TRUE
);
5322 return localized_name
;
5324 #endif // !TARGET_OS_IPHONE
5328 __SCNetworkInterfaceSetUserDefinedName(SCNetworkInterfaceRef interface
, CFStringRef name
)
5330 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5332 if (!isA_SCNetworkInterface(interface
)) {
5338 if (interfacePrivate
->name
!= NULL
) {
5339 CFRelease(interfacePrivate
->name
);
5341 interfacePrivate
->name
= name
;
5346 if (interfacePrivate
->localized_name
!= NULL
) {
5347 CFRelease(interfacePrivate
->localized_name
);
5349 interfacePrivate
->localized_name
= name
;
5354 __SCNetworkInterfaceGetUserDefinedName(SCNetworkInterfaceRef interface
)
5356 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5358 if (!isA_SCNetworkInterface(interface
)) {
5362 return interfacePrivate
->name
;
5368 __SCNetworkInterfaceGetNonLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5370 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5372 if (!isA_SCNetworkInterface(interface
)) {
5373 _SCErrorSet(kSCStatusInvalidArgument
);
5377 if (interfacePrivate
->name
== NULL
) {
5378 interfacePrivate
->name
= copy_display_name(interface
, FALSE
, FALSE
);
5381 return interfacePrivate
->name
;
5386 SCNetworkInterfaceGetLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5388 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5390 if (!isA_SCNetworkInterface(interface
)) {
5391 _SCErrorSet(kSCStatusInvalidArgument
);
5395 if (interfacePrivate
->localized_name
== NULL
) {
5396 interfacePrivate
->localized_name
= copy_display_name(interface
, TRUE
, FALSE
);
5399 return interfacePrivate
->localized_name
;
5405 __SCNetworkInterfaceGetTemplateOverrides(SCNetworkInterfaceRef interface
, CFStringRef overrideType
)
5407 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5408 CFDictionaryRef overrides
= NULL
;
5410 if (interfacePrivate
->overrides
!= NULL
) {
5411 overrides
= CFDictionaryGetValue(interfacePrivate
->overrides
, overrideType
);
5419 SCNetworkInterfaceGetTypeID(void)
5421 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
); /* initialize runtime */
5422 return __kSCNetworkInterfaceTypeID
;
5428 __SCNetworkInterfaceSetDefaultConfiguration(SCNetworkSetRef set
,
5429 SCNetworkInterfaceRef interface
,
5430 CFStringRef defaultType
,
5431 CFDictionaryRef config
,
5434 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5437 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5438 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5440 if (defaultType
== NULL
) {
5441 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5442 if (defaultType
== NULL
) {
5447 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5454 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
5455 SCNetworkSetGetSetID(set
), // set
5456 interfacePrivate
->entity_device
, // interface
5457 defaultType
); // entity
5459 ok
= __setPrefsConfiguration(interfacePrivate
->prefs
, path
, config
, FALSE
);
5462 // if configuration has been saved
5463 if (interfacePrivate
->unsaved
!= NULL
) {
5464 CFDictionaryRemoveValue(interfacePrivate
->unsaved
, defaultType
);
5465 if (CFDictionaryGetCount(interfacePrivate
->unsaved
) == 0) {
5466 CFRelease(interfacePrivate
->unsaved
);
5467 interfacePrivate
->unsaved
= NULL
;
5473 if (config
== NULL
) {
5474 // remember that we are clearing the configuration
5475 config
= (CFDictionaryRef
)kCFNull
;
5478 if (interfacePrivate
->unsaved
== NULL
) {
5479 interfacePrivate
->unsaved
= CFDictionaryCreateMutable(NULL
,
5481 &kCFTypeDictionaryKeyCallBacks
,
5482 &kCFTypeDictionaryValueCallBacks
);
5484 CFDictionarySetValue(interfacePrivate
->unsaved
, defaultType
, config
);
5487 _SCErrorSet(kSCStatusNoKey
);
5498 __SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface
,
5499 CFStringRef extendedType
,
5500 CFDictionaryRef config
,
5503 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5507 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5508 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5510 if (extendedType
== NULL
) {
5511 extendedType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5512 if (extendedType
== NULL
) {
5517 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5521 paths
= copyConfigurationPaths(interfacePrivate
, extendedType
);
5522 if (paths
!= NULL
) {
5526 n
= CFArrayGetCount(paths
);
5527 for (i
= 0; i
< n
; i
++) {
5530 path
= CFArrayGetValueAtIndex(paths
, i
);
5531 ok
= __setPrefsConfiguration(interfacePrivate
->prefs
, path
, config
, FALSE
);
5538 // if configuration has been saved
5539 if (interfacePrivate
->unsaved
!= NULL
) {
5540 CFDictionaryRemoveValue(interfacePrivate
->unsaved
, extendedType
);
5541 if (CFDictionaryGetCount(interfacePrivate
->unsaved
) == 0) {
5542 CFRelease(interfacePrivate
->unsaved
);
5543 interfacePrivate
->unsaved
= NULL
;
5551 if (config
== NULL
) {
5552 // remember that we are clearing the configuration
5553 config
= (CFDictionaryRef
)kCFNull
;
5556 if (interfacePrivate
->unsaved
== NULL
) {
5557 interfacePrivate
->unsaved
= CFDictionaryCreateMutable(NULL
,
5559 &kCFTypeDictionaryKeyCallBacks
,
5560 &kCFTypeDictionaryValueCallBacks
);
5562 CFDictionarySetValue(interfacePrivate
->unsaved
, extendedType
, config
);
5565 _SCErrorSet(kSCStatusNoKey
);
5574 SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface
, CFDictionaryRef config
)
5576 CFStringRef defaultType
;
5578 if (!isA_SCNetworkInterface(interface
)) {
5579 _SCErrorSet(kSCStatusInvalidArgument
);
5583 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5584 if (defaultType
== NULL
) {
5588 return __SCNetworkInterfaceSetConfiguration(interface
, defaultType
, config
, FALSE
);
5593 SCNetworkInterfaceSetExtendedConfiguration(SCNetworkInterfaceRef interface
,
5594 CFStringRef extendedType
,
5595 CFDictionaryRef config
)
5597 if (!isA_SCNetworkInterface(interface
)) {
5598 _SCErrorSet(kSCStatusInvalidArgument
);
5602 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, TRUE
)) {
5606 return __SCNetworkInterfaceSetConfiguration(interface
, extendedType
, config
, FALSE
);
5611 #pragma mark SCNetworkInterface [Refresh Configuration] API
5614 #ifndef kSCEntNetRefreshConfiguration
5615 #define kSCEntNetRefreshConfiguration CFSTR("RefreshConfiguration")
5616 #endif // kSCEntNetRefreshConfiguration
5619 _SCNetworkInterfaceForceConfigurationRefresh(CFStringRef ifName
)
5624 if (!isA_CFString(ifName
)) {
5625 _SCErrorSet(kSCStatusInvalidArgument
);
5629 key
= SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL
,
5630 kSCDynamicStoreDomainState
,
5632 kSCEntNetRefreshConfiguration
);
5633 ok
= SCDynamicStoreNotifyValue(NULL
, key
);
5640 __SCNetworkInterfaceForceConfigurationRefresh_helper(SCPreferencesRef prefs
, CFStringRef ifName
)
5642 CFDataRef data
= NULL
;
5644 SCPreferencesPrivateRef prefsPrivate
= (SCPreferencesPrivateRef
)prefs
;
5645 uint32_t status
= kSCStatusOK
;
5646 CFDataRef reply
= NULL
;
5648 if (prefsPrivate
->helper_port
== MACH_PORT_NULL
) {
5649 ok
= __SCPreferencesCreate_helper(prefs
);
5655 // serialize the interface name
5656 ok
= _SCSerializeString(ifName
, &data
, NULL
, NULL
);
5661 // have the helper "refresh" the configuration
5662 status
= kSCStatusOK
;
5664 ok
= _SCHelperExec(prefsPrivate
->helper_port
,
5665 SCHELPER_MSG_INTERFACE_REFRESH
,
5669 if (data
!= NULL
) CFRelease(data
);
5674 if (status
!= kSCStatusOK
) {
5683 if (prefsPrivate
->helper_port
!= MACH_PORT_NULL
) {
5684 _SCHelperClose(&prefsPrivate
->helper_port
);
5687 status
= kSCStatusAccessError
;
5692 _SCErrorSet(status
);
5698 SCNetworkInterfaceForceConfigurationRefresh(SCNetworkInterfaceRef interface
)
5701 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5703 if (!isA_SCNetworkInterface(interface
)) {
5704 _SCErrorSet(kSCStatusInvalidArgument
);
5708 ifName
= SCNetworkInterfaceGetBSDName(interface
);
5709 if (ifName
== NULL
) {
5710 _SCErrorSet(kSCStatusInvalidArgument
);
5714 if (interfacePrivate
->prefs
!= NULL
) {
5715 SCPreferencesRef prefs
= interfacePrivate
->prefs
;
5716 SCPreferencesPrivateRef prefsPrivate
= (SCPreferencesPrivateRef
)prefs
;
5718 if (prefsPrivate
->authorizationData
!= NULL
) {
5719 return __SCNetworkInterfaceForceConfigurationRefresh_helper(prefs
, ifName
);
5723 return _SCNetworkInterfaceForceConfigurationRefresh(ifName
);
5728 SCNetworkInterfaceRefreshConfiguration(CFStringRef ifName
)
5730 return _SCNetworkInterfaceForceConfigurationRefresh(ifName
);
5735 #pragma mark SCNetworkInterface Password APIs
5739 getPasswordID(CFDictionaryRef config
, CFStringRef serviceID
)
5741 CFStringRef unique_id
= NULL
;
5743 if (config
!= NULL
) {
5744 CFStringRef encryption
;
5746 encryption
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPasswordEncryption
);
5747 if (isA_CFString(encryption
) &&
5748 CFEqual(encryption
, kSCValNetPPPAuthPasswordEncryptionKeychain
)) {
5749 unique_id
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPassword
);
5752 if (unique_id
== NULL
) {
5753 unique_id
= serviceID
;
5761 copySharedSecretID(CFDictionaryRef config
, CFStringRef serviceID
)
5763 CFMutableStringRef shared_id
= NULL
;
5765 if (config
!= NULL
) {
5766 CFStringRef encryption
;
5768 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecretEncryption
);
5769 if (isA_CFString(encryption
) &&
5770 CFEqual(encryption
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) {
5771 shared_id
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecret
);
5772 if (shared_id
!= NULL
) {
5773 CFRetain(shared_id
);
5778 if (shared_id
== NULL
) {
5779 CFStringRef unique_id
;
5781 unique_id
= getPasswordID(config
, serviceID
);
5782 shared_id
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
5783 CFStringAppend(shared_id
, CFSTR(".SS"));
5791 copyXAuthID(CFDictionaryRef config
, CFStringRef serviceID
)
5793 CFMutableStringRef xauth_id
= NULL
;
5795 if (config
!= NULL
) {
5796 CFStringRef encryption
;
5798 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPasswordEncryption
);
5799 if (isA_CFString(encryption
) &&
5800 CFEqual(encryption
, kSCValNetIPSecXAuthPasswordEncryptionKeychain
)) {
5801 xauth_id
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPassword
);
5802 if (xauth_id
!= NULL
) {
5808 if (xauth_id
== NULL
) {
5809 CFStringRef unique_id
;
5811 unique_id
= getPasswordID(config
, serviceID
);
5812 xauth_id
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
5813 CFStringAppend(xauth_id
, CFSTR(".XAUTH"));
5821 checkInterfacePassword(SCNetworkInterfaceRef interface
,
5822 SCNetworkInterfacePasswordType passwordType
,
5823 SCPreferencesRef
*prefs
,
5824 CFStringRef
*serviceID
)
5826 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5828 if (!isA_SCNetworkInterface(interface
)) {
5832 *serviceID
= interfacePrivate
->serviceID
;
5833 if (*serviceID
== NULL
) {
5837 *prefs
= interfacePrivate
->prefs
;
5838 if (*prefs
== NULL
) {
5842 switch (passwordType
) {
5843 case kSCNetworkInterfacePasswordTypePPP
: {
5844 CFStringRef interfaceType
;
5846 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
5847 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
5855 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
5856 CFStringRef interfaceType
;
5858 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
5859 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
5860 interface
= SCNetworkInterfaceGetInterface(interface
);
5861 if (interface
!= NULL
) {
5862 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
5863 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
5864 // if PPP->L2TP interface
5868 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
5869 // if IPSec interface
5876 case kSCNetworkInterfacePasswordTypeEAPOL
: {
5880 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
5881 CFStringRef interfaceType
;
5883 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
5884 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
5885 // if IPSec interface
5892 case kSCNetworkInterfacePasswordTypeVPN
: {
5893 CFStringRef interfaceType
;
5895 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
5896 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) {
5912 _SCErrorSet(kSCStatusInvalidArgument
);
5918 SCNetworkInterfaceCheckPassword(SCNetworkInterfaceRef interface
,
5919 SCNetworkInterfacePasswordType passwordType
)
5921 Boolean exists
= FALSE
;
5922 SCPreferencesRef prefs
= NULL
;
5923 CFStringRef serviceID
= NULL
;
5925 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
5929 switch (passwordType
) {
5930 case kSCNetworkInterfacePasswordTypePPP
: {
5931 CFDictionaryRef config
;
5932 CFStringRef unique_id
;
5934 // get configuration
5935 config
= SCNetworkInterfaceGetConfiguration(interface
);
5938 unique_id
= getPasswordID(config
, serviceID
);
5941 exists
= __extract_password(prefs
,
5943 kSCPropNetPPPAuthPassword
,
5944 kSCPropNetPPPAuthPasswordEncryption
,
5945 kSCValNetPPPAuthPasswordEncryptionKeychain
,
5951 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
5952 CFDictionaryRef config
;
5954 CFStringRef shared_id
;
5956 // get configuration
5957 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
5959 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
5961 config
= SCNetworkInterfaceGetConfiguration(interface
);
5964 // get sharedSecret ID
5965 shared_id
= copySharedSecretID(config
, serviceID
);
5968 exists
= __extract_password(prefs
,
5970 kSCPropNetIPSecSharedSecret
,
5971 kSCPropNetIPSecSharedSecretEncryption
,
5972 kSCValNetIPSecSharedSecretEncryptionKeychain
,
5975 CFRelease(shared_id
);
5979 case kSCNetworkInterfacePasswordTypeEAPOL
: {
5980 CFDictionaryRef config
;
5981 CFStringRef unique_id
= NULL
;
5983 // get configuration
5984 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
5986 // get 802.1X identifier
5987 if (config
!= NULL
) {
5988 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
5990 if (!isA_CFString(unique_id
)) {
5995 exists
= _SCPreferencesSystemKeychainPasswordItemExists(prefs
, unique_id
);
5999 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6000 CFDictionaryRef config
;
6001 CFStringRef xauth_id
;
6003 // get configuration
6004 config
= SCNetworkInterfaceGetConfiguration(interface
);
6007 xauth_id
= copyXAuthID(config
, serviceID
);
6010 exists
= __extract_password(prefs
,
6012 kSCPropNetIPSecXAuthPassword
,
6013 kSCPropNetIPSecXAuthPasswordEncryption
,
6014 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
6017 CFRelease(xauth_id
);
6021 case kSCNetworkInterfacePasswordTypeVPN
: {
6022 CFDictionaryRef config
;
6025 // get configuration
6026 config
= SCNetworkInterfaceGetConfiguration(interface
);
6029 vpn_id
= getPasswordID(config
, serviceID
);
6032 exists
= __extract_password(prefs
,
6034 kSCPropNetVPNAuthPassword
,
6035 kSCPropNetVPNAuthPasswordEncryption
,
6036 kSCValNetVPNAuthPasswordEncryptionKeychain
,
6043 _SCErrorSet(kSCStatusInvalidArgument
);
6052 SCNetworkInterfaceCopyPassword(SCNetworkInterfaceRef interface
,
6053 SCNetworkInterfacePasswordType passwordType
)
6055 CFDataRef password
= NULL
;
6056 SCPreferencesRef prefs
= NULL
;
6057 CFStringRef serviceID
= NULL
;
6059 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6063 switch (passwordType
) {
6064 case kSCNetworkInterfacePasswordTypePPP
: {
6065 CFDictionaryRef config
;
6066 CFStringRef unique_id
;
6068 // get configuration
6069 config
= SCNetworkInterfaceGetConfiguration(interface
);
6072 unique_id
= getPasswordID(config
, serviceID
);
6075 (void) __extract_password(prefs
,
6077 kSCPropNetPPPAuthPassword
,
6078 kSCPropNetPPPAuthPasswordEncryption
,
6079 kSCValNetPPPAuthPasswordEncryptionKeychain
,
6085 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6086 CFDictionaryRef config
;
6088 CFStringRef shared_id
;
6090 // get configuration
6091 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6093 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6095 config
= SCNetworkInterfaceGetConfiguration(interface
);
6098 // get sharedSecret ID
6099 shared_id
= copySharedSecretID(config
, serviceID
);
6102 (void) __extract_password(prefs
,
6104 kSCPropNetIPSecSharedSecret
,
6105 kSCPropNetIPSecSharedSecretEncryption
,
6106 kSCValNetIPSecSharedSecretEncryptionKeychain
,
6110 CFRelease(shared_id
);
6114 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6115 CFDictionaryRef config
;
6116 CFStringRef unique_id
= NULL
;
6118 // get configuration
6119 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6121 // get 802.1X identifier
6122 if (config
!= NULL
) {
6123 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6125 if (!isA_CFString(unique_id
)) {
6126 _SCErrorSet(kSCStatusFailed
);
6131 password
= _SCPreferencesSystemKeychainPasswordItemCopy(prefs
, unique_id
);
6135 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6136 CFDictionaryRef config
;
6137 CFStringRef xauth_id
;
6139 // get configuration
6140 config
= SCNetworkInterfaceGetConfiguration(interface
);
6143 xauth_id
= copyXAuthID(config
, serviceID
);
6146 (void) __extract_password(prefs
,
6148 kSCPropNetIPSecXAuthPassword
,
6149 kSCPropNetIPSecXAuthPasswordEncryption
,
6150 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
6153 CFRelease(xauth_id
);
6157 case kSCNetworkInterfacePasswordTypeVPN
: {
6158 CFDictionaryRef config
;
6161 // get configuration
6162 config
= SCNetworkInterfaceGetConfiguration(interface
);
6165 vpn_id
= getPasswordID(config
, serviceID
);
6168 (void) __extract_password(prefs
,
6170 kSCPropNetVPNAuthPassword
,
6171 kSCPropNetVPNAuthPasswordEncryption
,
6172 kSCValNetVPNAuthPasswordEncryptionKeychain
,
6179 _SCErrorSet(kSCStatusInvalidArgument
);
6188 SCNetworkInterfaceRemovePassword(SCNetworkInterfaceRef interface
,
6189 SCNetworkInterfacePasswordType passwordType
)
6192 SCPreferencesRef prefs
= NULL
;
6193 CFStringRef serviceID
= NULL
;
6195 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6199 switch (passwordType
) {
6200 case kSCNetworkInterfacePasswordTypePPP
: {
6201 CFDictionaryRef config
;
6202 CFDictionaryRef newConfig
= NULL
;
6203 CFStringRef unique_id
;
6205 // get configuration
6206 config
= SCNetworkInterfaceGetConfiguration(interface
);
6209 unique_id
= getPasswordID(config
, serviceID
);
6212 ok
= __remove_password(prefs
,
6214 kSCPropNetPPPAuthPassword
,
6215 kSCPropNetPPPAuthPasswordEncryption
,
6216 kSCValNetPPPAuthPasswordEncryptionKeychain
,
6220 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6221 if (newConfig
!= NULL
) CFRelease(newConfig
);
6227 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6228 CFDictionaryRef config
;
6230 CFDictionaryRef newConfig
= NULL
;
6231 CFStringRef shared_id
;
6233 // get configuration
6234 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6236 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6238 config
= SCNetworkInterfaceGetConfiguration(interface
);
6241 // get sharedSecret ID
6242 shared_id
= copySharedSecretID(config
, serviceID
);
6245 ok
= __remove_password(prefs
,
6247 kSCPropNetIPSecSharedSecret
,
6248 kSCPropNetIPSecSharedSecretEncryption
,
6249 kSCValNetIPSecSharedSecretEncryptionKeychain
,
6254 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
6258 ok
= SCNetworkInterfaceSetConfiguration(interface
,
6261 if (newConfig
!= NULL
) CFRelease(newConfig
);
6264 CFRelease(shared_id
);
6268 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6269 CFDictionaryRef config
;
6270 CFStringRef unique_id
= NULL
;
6272 // get configuration
6273 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6275 // get 802.1X identifier
6276 if (config
!= NULL
) {
6277 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6279 if (!isA_CFString(unique_id
)) {
6280 _SCErrorSet(kSCStatusFailed
);
6285 ok
= _SCPreferencesSystemKeychainPasswordItemRemove(prefs
, unique_id
);
6289 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6290 CFDictionaryRef config
;
6291 CFDictionaryRef newConfig
= NULL
;
6292 CFStringRef xauth_id
;
6294 // get configuration
6295 config
= SCNetworkInterfaceGetConfiguration(interface
);
6298 xauth_id
= copyXAuthID(config
, serviceID
);
6301 ok
= __remove_password(prefs
,
6303 kSCPropNetIPSecXAuthPassword
,
6304 kSCPropNetIPSecXAuthPasswordEncryption
,
6305 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
6309 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6310 if (newConfig
!= NULL
) CFRelease(newConfig
);
6313 CFRelease(xauth_id
);
6317 case kSCNetworkInterfacePasswordTypeVPN
: {
6318 CFDictionaryRef config
;
6319 CFDictionaryRef newConfig
= NULL
;
6322 // get configuration
6323 config
= SCNetworkInterfaceGetConfiguration(interface
);
6326 vpn_id
= getPasswordID(config
, serviceID
);
6329 ok
= __remove_password(prefs
,
6331 kSCPropNetVPNAuthPassword
,
6332 kSCPropNetVPNAuthPasswordEncryption
,
6333 kSCValNetVPNAuthPasswordEncryptionKeychain
,
6337 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6338 if (newConfig
!= NULL
) CFRelease(newConfig
);
6344 _SCErrorSet(kSCStatusInvalidArgument
);
6353 SCNetworkInterfaceSetPassword(SCNetworkInterfaceRef interface
,
6354 SCNetworkInterfacePasswordType passwordType
,
6356 CFDictionaryRef options
)
6358 CFStringRef account
= NULL
;
6359 CFDictionaryRef config
;
6360 CFStringRef description
= NULL
;
6361 CFStringRef label
= NULL
;
6363 SCPreferencesRef prefs
= NULL
;
6364 CFStringRef serviceID
= NULL
;
6366 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6370 switch (passwordType
) {
6371 case kSCNetworkInterfacePasswordTypePPP
: {
6372 SCNetworkServiceRef service
= NULL
;
6373 CFStringRef unique_id
;
6375 // get configuration
6376 config
= SCNetworkInterfaceGetConfiguration(interface
);
6379 unique_id
= getPasswordID(config
, serviceID
);
6381 // get "Account", "Name", "Kind"
6382 if (config
!= NULL
) {
6383 // auth name --> keychain "Account"
6384 account
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthName
);
6386 // PPP [user defined] "name" --> keychain "Name"
6387 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6390 if (label
== NULL
) {
6391 // service name --> keychain "Name"
6392 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
6397 label
= SCNetworkServiceGetName(service
);
6398 if (label
== NULL
) {
6399 // interface name --> keychain "Name"
6400 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6404 if (bundle
!= NULL
) {
6405 // "PPP Password" --> keychain "Kind"
6406 description
= CFBundleCopyLocalizedString(bundle
,
6407 CFSTR("KEYCHAIN_KIND_PPP_PASSWORD"),
6408 CFSTR("PPP Password"),
6413 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6415 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6416 (description
!= NULL
) ? description
: CFSTR("PPP Password"),
6421 CFMutableDictionaryRef newConfig
;
6423 if (config
!= NULL
) {
6424 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6426 newConfig
= CFDictionaryCreateMutable(NULL
,
6428 &kCFTypeDictionaryKeyCallBacks
,
6429 &kCFTypeDictionaryValueCallBacks
);
6431 CFDictionarySetValue(newConfig
,
6432 kSCPropNetPPPAuthPassword
,
6434 CFDictionarySetValue(newConfig
,
6435 kSCPropNetPPPAuthPasswordEncryption
,
6436 kSCValNetPPPAuthPasswordEncryptionKeychain
);
6437 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6438 CFRelease(newConfig
);
6441 if (description
!= NULL
) CFRelease(description
);
6442 if (service
!= NULL
) CFRelease(service
);
6446 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6447 CFDictionaryRef baseConfig
= NULL
;
6449 SCNetworkServiceRef service
= NULL
;
6450 CFStringRef shared_id
;
6452 // get configuration
6453 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6454 config
= SCNetworkInterfaceGetConfiguration(interface
);
6456 baseConfig
= config
;
6457 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6460 // get sharedSecret ID
6461 shared_id
= copySharedSecretID(config
, serviceID
);
6463 // get "Account", "Name", "Kind"
6464 if (config
!= NULL
) {
6465 CFStringRef localIdentifier
;
6466 CFStringRef localIdentifierType
;
6468 if (CFDictionaryGetValueIfPresent(config
,
6469 kSCPropNetIPSecLocalIdentifierType
,
6470 (const void **)&localIdentifierType
)
6471 && CFEqual(localIdentifierType
, kSCValNetIPSecLocalIdentifierTypeKeyID
)
6472 && CFDictionaryGetValueIfPresent(config
,
6473 kSCPropNetIPSecLocalIdentifier
,
6474 (const void **)&localIdentifier
)
6475 && isA_CFString(localIdentifier
)) {
6476 // local identifier --> keychain "Account"
6477 account
= localIdentifier
;
6480 // PPP [user defined] "name" --> keychain "Name"
6482 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6484 if (baseConfig
!= NULL
) {
6485 label
= CFDictionaryGetValue(baseConfig
, kSCPropUserDefinedName
);
6490 if (label
== NULL
) {
6491 // service name --> keychain "Name"
6492 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
6497 label
= SCNetworkServiceGetName(service
);
6498 if (label
== NULL
) {
6499 // interface name --> keychain "Name"
6500 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6504 if (bundle
!= NULL
) {
6505 // "IPSec Shared Secret" --> keychain "Kind"
6506 description
= CFBundleCopyLocalizedString(bundle
,
6507 CFSTR("KEYCHAIN_KIND_IPSEC_SHARED_SECRET"),
6508 CFSTR("IPSec Shared Secret"),
6513 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6515 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6516 (description
!= NULL
) ? description
: CFSTR("IPSec Shared Secret"),
6521 CFMutableDictionaryRef newConfig
= NULL
;
6523 if (config
!= NULL
) {
6524 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6526 newConfig
= CFDictionaryCreateMutable(NULL
,
6528 &kCFTypeDictionaryKeyCallBacks
,
6529 &kCFTypeDictionaryValueCallBacks
);
6531 CFDictionarySetValue(newConfig
,
6532 kSCPropNetIPSecSharedSecret
,
6534 CFDictionarySetValue(newConfig
,
6535 kSCPropNetIPSecSharedSecretEncryption
,
6536 kSCValNetIPSecSharedSecretEncryptionKeychain
);
6538 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
6542 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6544 CFRelease(newConfig
);
6547 if (description
!= NULL
) CFRelease(description
);
6548 if (service
!= NULL
) CFRelease(service
);
6549 CFRelease(shared_id
);
6553 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6554 CFStringRef account
= NULL
;
6555 CFStringRef unique_id
= NULL
;
6557 // get configuration
6558 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6560 // get 802.1X identifier
6561 if (config
!= NULL
) {
6562 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6563 unique_id
= isA_CFString(unique_id
);
6565 if (unique_id
!= NULL
) {
6566 CFRetain(unique_id
);
6570 uuid
= CFUUIDCreate(NULL
);
6571 unique_id
= CFUUIDCreateString(NULL
, uuid
);
6575 // 802.1x UserName --> keychain "Account"
6576 if (config
!= NULL
) {
6577 account
= CFDictionaryGetValue(config
, kEAPClientPropUserName
);
6580 // get "Name", "Kind"
6581 if (bundle
!= NULL
) {
6582 CFStringRef interface_name
;
6584 // "Network Connection (%@)" --> keychain "Name"
6585 interface_name
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6586 if (interface_name
!= NULL
) {
6587 CFStringRef label_fmt
;
6589 label_fmt
= CFBundleCopyLocalizedString(bundle
,
6590 CFSTR("KEYCHAIN_DESCRIPTION_EAPOL_INTERFACE"),
6591 CFSTR("Network Connection (%@)"),
6593 label
= CFStringCreateWithFormat(NULL
, NULL
, label_fmt
, interface_name
);
6594 CFRelease(label_fmt
);
6596 label
= CFBundleCopyLocalizedString(bundle
,
6597 CFSTR("KEYCHAIN_DESCRIPTION_EAPOL"),
6598 CFSTR("Network Connection"),
6602 // "802.1X Password" --> keychain "Kind"
6603 description
= CFBundleCopyLocalizedString(bundle
,
6604 CFSTR("KEYCHAIN_KIND_EAPOL"),
6605 CFSTR("802.1X Password"),
6610 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6612 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6613 (description
!= NULL
) ? description
: CFSTR("802.1X Password"),
6618 CFMutableDictionaryRef newConfig
= NULL
;
6620 if (config
!= NULL
) {
6621 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6623 newConfig
= CFDictionaryCreateMutable(NULL
,
6625 &kCFTypeDictionaryKeyCallBacks
,
6626 &kCFTypeDictionaryValueCallBacks
);
6628 CFDictionarySetValue(newConfig
,
6629 kEAPClientPropUserPasswordKeychainItemID
,
6631 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
6634 CFRelease(newConfig
);
6637 CFRelease(unique_id
);
6638 if (label
!= NULL
) CFRelease(label
);
6639 if (description
!= NULL
) CFRelease(description
);
6643 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6644 SCNetworkServiceRef service
= NULL
;
6645 CFStringRef xauth_id
;
6647 // get configuration
6648 config
= SCNetworkInterfaceGetConfiguration(interface
);
6651 xauth_id
= copyXAuthID(config
, serviceID
);
6653 // get "Account", "Name", "Kind"
6654 if (config
!= NULL
) {
6655 // auth name --> keychain "Account"
6656 account
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthName
);
6658 // IPSec [user defined] "name" --> keychain "Name"
6659 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6662 if (label
== NULL
) {
6663 // service name --> keychain "Name"
6664 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
6669 label
= SCNetworkServiceGetName(service
);
6670 if (label
== NULL
) {
6671 // interface name --> keychain "Name"
6672 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6676 if (bundle
!= NULL
) {
6677 // "IPSec XAuth Password" --> keychain "Kind"
6678 description
= CFBundleCopyLocalizedString(bundle
,
6679 CFSTR("KEYCHAIN_KIND_IPSEC_XAUTH_PASSWORD"),
6680 CFSTR("IPSec XAuth Password"),
6685 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6687 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6688 (description
!= NULL
) ? description
: CFSTR("IPSec XAuth Password"),
6693 CFMutableDictionaryRef newConfig
;
6695 if (config
!= NULL
) {
6696 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6698 newConfig
= CFDictionaryCreateMutable(NULL
,
6700 &kCFTypeDictionaryKeyCallBacks
,
6701 &kCFTypeDictionaryValueCallBacks
);
6703 CFDictionarySetValue(newConfig
,
6704 kSCPropNetIPSecXAuthPassword
,
6706 CFDictionarySetValue(newConfig
,
6707 kSCPropNetIPSecXAuthPasswordEncryption
,
6708 kSCValNetIPSecXAuthPasswordEncryptionKeychain
);
6709 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6710 CFRelease(newConfig
);
6713 CFRelease(xauth_id
);
6714 if (description
!= NULL
) CFRelease(description
);
6715 if (service
!= NULL
) CFRelease(service
);
6719 case kSCNetworkInterfacePasswordTypeVPN
: {
6720 SCNetworkServiceRef service
= NULL
;
6723 // get configuration
6724 config
= SCNetworkInterfaceGetConfiguration(interface
);
6727 vpn_id
= getPasswordID(config
, serviceID
);
6729 // get "Account", "Name", "Kind"
6730 if (config
!= NULL
) {
6731 // auth name --> keychain "Account"
6732 account
= CFDictionaryGetValue(config
, kSCPropNetVPNAuthName
);
6734 // VPN [user defined] "name" --> keychain "Name"
6735 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6738 if (label
== NULL
) {
6739 // service name --> keychain "Name"
6740 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
6745 label
= SCNetworkServiceGetName(service
);
6746 if (label
== NULL
) {
6747 // interface name --> keychain "Name"
6748 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6752 if (bundle
!= NULL
) {
6753 // "VPN Password" --> keychain "Kind"
6754 description
= CFBundleCopyLocalizedString(bundle
,
6755 CFSTR("KEYCHAIN_KIND_VPN_PASSWORD"),
6756 CFSTR("VPN Password"),
6761 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6763 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6764 (description
!= NULL
) ? description
: CFSTR("VPN Password"),
6769 CFMutableDictionaryRef newConfig
;
6771 if (config
!= NULL
) {
6772 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6774 newConfig
= CFDictionaryCreateMutable(NULL
,
6776 &kCFTypeDictionaryKeyCallBacks
,
6777 &kCFTypeDictionaryValueCallBacks
);
6779 CFDictionarySetValue(newConfig
,
6780 kSCPropNetVPNAuthPassword
,
6782 CFDictionarySetValue(newConfig
,
6783 kSCPropNetVPNAuthPasswordEncryption
,
6784 kSCValNetVPNAuthPasswordEncryptionKeychain
);
6785 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6786 CFRelease(newConfig
);
6789 if (description
!= NULL
) CFRelease(description
);
6790 if (service
!= NULL
) CFRelease(service
);
6795 _SCErrorSet(kSCStatusInvalidArgument
);
6804 #pragma mark SCNetworkInterface [InterfaceNamer] SPIs
6808 _SCNetworkInterfaceCopyInterfaceInfo(SCNetworkInterfaceRef interface
)
6810 CFMutableDictionaryRef info
;
6811 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6814 if (interface
== NULL
) {
6818 info
= CFDictionaryCreateMutable(NULL
,
6820 &kCFTypeDictionaryKeyCallBacks
,
6821 &kCFTypeDictionaryValueCallBacks
);
6823 // add non-localized interface name
6824 name
= __SCNetworkInterfaceGetNonLocalizedDisplayName(interface
);
6826 CFDictionaryAddValue(info
, kSCPropUserDefinedName
, name
);
6830 if ((interfacePrivate
->usb
.vid
!= NULL
) || (interfacePrivate
->usb
.pid
!= NULL
)) {
6831 #if !TARGET_IPHONE_SIMULATOR
6832 if (interfacePrivate
->usb
.name
!= NULL
) {
6833 CFDictionaryAddValue(info
, CFSTR(kUSBProductString
), interfacePrivate
->usb
.name
);
6835 if (interfacePrivate
->usb
.vid
!= NULL
) {
6836 CFDictionaryAddValue(info
, CFSTR(kUSBVendorID
), interfacePrivate
->usb
.vid
);
6838 if (interfacePrivate
->usb
.pid
!= NULL
) {
6839 CFDictionaryAddValue(info
, CFSTR(kUSBProductID
), interfacePrivate
->usb
.pid
);
6841 #endif // !TARGET_IPHONE_SIMULATOR
6844 if (CFDictionaryGetCount(info
) == 0) {
6845 // do not return an empty dictionary
6854 SCNetworkInterfaceRef
6855 _SCNetworkInterfaceCreateWithIONetworkInterfaceObject(io_object_t if_obj
)
6857 SCNetworkInterfaceRef interface
= NULL
;
6859 /* initialize runtime */
6860 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
6862 if (IOObjectConformsTo(if_obj
, kIONetworkInterfaceClass
)) {
6863 interface
= createInterface(if_obj
, processNetworkInterface
, NULL
);
6864 } else if (IOObjectConformsTo(if_obj
, kIOSerialBSDServiceValue
)) {
6865 interface
= createInterface(if_obj
, processSerialInterface
, kSCNetworkInterfaceHiddenPortKey
);
6873 _SCNetworkInterfaceGetConfigurationAction(SCNetworkInterfaceRef interface
)
6875 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6877 return interfacePrivate
->configurationAction
;
6882 _SCNetworkInterfaceGetHardwareAddress(SCNetworkInterfaceRef interface
)
6884 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6886 return interfacePrivate
->address
;
6891 _SCNetworkInterfaceGetIOInterfaceNamePrefix(SCNetworkInterfaceRef interface
)
6893 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6895 return interfacePrivate
->prefix
;
6900 _SCNetworkInterfaceGetIOInterfaceType(SCNetworkInterfaceRef interface
)
6902 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6904 return interfacePrivate
->type
;
6909 _SCNetworkInterfaceGetIOInterfaceUnit(SCNetworkInterfaceRef interface
)
6911 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6913 return interfacePrivate
->unit
;
6918 _SCNetworkInterfaceGetIOPath(SCNetworkInterfaceRef interface
)
6920 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6922 return interfacePrivate
->path
;
6927 _SCNetworkInterfaceGetIORegistryEntryID(SCNetworkInterfaceRef interface
)
6929 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6931 return interfacePrivate
->entryID
;
6937 __SCNetworkInterfaceIsActive (SCNetworkInterfaceRef interface
)
6939 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6941 return interfacePrivate
->active
;
6946 _SCNetworkInterfaceIsBuiltin(SCNetworkInterfaceRef interface
)
6948 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6950 return interfacePrivate
->builtin
;
6955 #pragma mark SCNetworkInterface SPIs
6958 #if !TARGET_OS_EMBEDDED
6960 SCNetworkInterfaceRef
6961 _SCNetworkInterfaceCopyBTPANInterface(void)
6963 CFDictionaryRef dict
;
6964 SCNetworkInterfaceRef interface
= NULL
;
6967 key
= SCDynamicStoreKeyCreate(NULL
, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin
);
6968 dict
= SCDynamicStoreCopyValue(NULL
, key
);
6972 CFStringRef if_name
;
6973 SCNetworkInterfacePrivateRef interfacePrivate
;
6975 if (isA_CFDictionary(dict
) &&
6976 CFDictionaryGetValueIfPresent(dict
,
6977 CFSTR("_" BT_PAN_NAME
"_"),
6978 (const void **)&if_name
) &&
6979 isA_CFString(if_name
)) {
6980 CFMutableDictionaryRef entity
;
6982 entity
= CFDictionaryCreateMutable(NULL
,
6984 &kCFTypeDictionaryKeyCallBacks
,
6985 &kCFTypeDictionaryValueCallBacks
);
6986 CFDictionarySetValue(entity
,
6987 kSCPropNetInterfaceType
,
6988 kSCValNetInterfaceTypeEthernet
);
6989 CFDictionarySetValue(entity
,
6990 kSCPropNetInterfaceDeviceName
,
6992 CFDictionarySetValue(entity
,
6993 kSCPropUserDefinedName
,
6994 CFSTR(BT_PAN_NAME
));
6995 interface
= _SCNetworkInterfaceCreateWithEntity(NULL
, entity
, NULL
);
6999 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7001 if ((interfacePrivate
!= NULL
) &&
7002 (interfacePrivate
->address
== NULL
) &&
7003 CFDictionaryGetValueIfPresent(dict
,
7004 CFSTR("_" BT_PAN_MAC
"_"),
7005 (const void **)&addr
) &&
7007 interfacePrivate
->address
= CFRetain(addr
);
7015 #endif // !TARGET_OS_EMBEDDED
7019 _SCNetworkInterfaceCopySlashDevPath(SCNetworkInterfaceRef interface
)
7021 io_registry_entry_t device
;
7022 io_iterator_t device_iterator
= MACH_PORT_NULL
;
7023 CFStringRef device_path
= NULL
;
7024 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7026 CFStringRef match_keys
[2];
7027 CFTypeRef match_vals
[2];
7028 CFDictionaryRef match_dict
;
7029 CFDictionaryRef matching
;
7031 if (interfacePrivate
->entity_device
== NULL
) {
7035 if (interfacePrivate
->entity_device_unique
== NULL
) {
7039 match_keys
[0] = CFSTR(kIOTTYBaseNameKey
);
7040 match_vals
[0] = interfacePrivate
->entity_device
;
7041 match_dict
= CFDictionaryCreate(NULL
,
7042 (const void **)match_keys
,
7043 (const void **)match_vals
,
7045 &kCFTypeDictionaryKeyCallBacks
,
7046 &kCFTypeDictionaryValueCallBacks
);
7048 match_keys
[0] = CFSTR(kIOProviderClassKey
);
7049 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
7050 match_keys
[1] = CFSTR(kIOPropertyMatchKey
);
7051 match_vals
[1] = match_dict
;
7052 matching
= CFDictionaryCreate(NULL
,
7053 (const void **)match_keys
,
7054 (const void **)match_vals
,
7055 sizeof(match_keys
)/sizeof(match_keys
[0]),
7056 &kCFTypeDictionaryKeyCallBacks
,
7057 &kCFTypeDictionaryValueCallBacks
);
7058 CFRelease(match_dict
);
7060 // note: this "matching" dictionary will be consumed by the call to IOServiceGetMatchingServices
7061 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &device_iterator
);
7062 if (kr
!= kIOReturnSuccess
) {
7063 SCLog(TRUE
, LOG_DEBUG
, CFSTR("IOServiceGetMatchingServices() failed, kr = 0x%x"), kr
);
7067 while ((device_path
== NULL
) &&
7068 ((device
= IOIteratorNext(device_iterator
)) != MACH_PORT_NULL
)) {
7069 CFDictionaryRef overrides
;
7071 overrides
= IORegistryEntrySearchCFProperty(device
,
7073 kSCNetworkInterfaceNetworkConfigurationOverridesKey
,
7075 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
7076 if (overrides
!= NULL
) {
7077 CFDictionaryRef modemOverrides
;
7079 modemOverrides
= CFDictionaryGetValue(overrides
, kSCEntNetModem
);
7080 if (modemOverrides
!= NULL
) {
7081 CFRetain(modemOverrides
);
7083 CFRelease(overrides
);
7084 overrides
= modemOverrides
;
7086 if (overrides
== NULL
) {
7087 overrides
= IORegistryEntrySearchCFProperty(device
,
7089 CFSTR("DeviceModemOverrides"),
7091 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
7093 if (overrides
!= NULL
) {
7094 if (isA_CFDictionary(overrides
)) {
7095 CFStringRef matchIdentifier
;
7097 matchIdentifier
= CFDictionaryGetValue(overrides
, CFSTR("UniqueIdentifier"));
7098 if (isA_CFString(matchIdentifier
) &&
7099 CFEqual(interfacePrivate
->entity_device_unique
, matchIdentifier
)) {
7100 device_path
= IORegistryEntryCreateCFProperty(device
,
7101 CFSTR(kIOTTYDeviceKey
),
7106 CFRelease(overrides
);
7108 IOObjectRelease(device
);
7111 IOObjectRelease(device_iterator
);
7115 if (device_path
== NULL
) {
7116 // if we haven't found an exact match to our UniqueIdentifier
7117 // so we simply return the base name.
7118 device_path
= SCNetworkInterfaceGetBSDName(interface
);
7119 if (device_path
!= NULL
) {
7120 CFRetain(device_path
);
7129 _SCNetworkInterfaceIsBluetoothPAN(SCNetworkInterfaceRef interface
)
7131 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7133 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_GN
);
7138 _SCNetworkInterfaceIsBluetoothPAN_NAP(SCNetworkInterfaceRef interface
)
7140 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7142 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_NAP
);
7147 _SCNetworkInterfaceIsBluetoothP2P(SCNetworkInterfaceRef interface
)
7149 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7151 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_U
);
7156 _SCNetworkInterfaceIsHiddenConfiguration(SCNetworkInterfaceRef interface
)
7158 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7160 return interfacePrivate
->hidden
;
7165 _SCNetworkInterfaceIsModemV92(SCNetworkInterfaceRef interface
)
7167 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7169 return interfacePrivate
->modemIsV92
;
7174 _SCNetworkInterfaceIsTethered(SCNetworkInterfaceRef interface
)
7176 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7178 return (interfacePrivate
->sort_order
== kSortTethered
);
7183 _SCNetworkInterfaceIsThunderbolt(SCNetworkInterfaceRef interface
)
7185 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7186 CFStringRef interfaceType
;
7188 if (!isA_SCNetworkInterface(interface
)) {
7192 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
7193 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeBridge
)) {
7198 members
= SCBridgeInterfaceGetMemberInterfaces(interface
);
7199 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
7201 // if an empty bridge
7205 for (i
= 0; i
< n
; i
++) {
7206 SCNetworkInterfaceRef member
;
7207 SCNetworkInterfacePrivateRef memberPrivate
;
7209 member
= CFArrayGetValueAtIndex(members
, i
);
7210 memberPrivate
= (SCNetworkInterfacePrivateRef
)member
;
7211 if (memberPrivate
->sort_order
!= kSortThunderbolt
) {
7216 // if Ethernet Bridge interface with only Thunderbolt [IP] members
7220 return (interfacePrivate
->sort_order
== kSortThunderbolt
);
7225 #pragma mark SCNetworkInterface [internal] SPIs
7229 SCNetworkInterfacePrivateRef
7230 __SCNetworkInterfaceCreateCopy(CFAllocatorRef allocator
,
7231 SCNetworkInterfaceRef interface
,
7232 SCPreferencesRef prefs
,
7233 CFStringRef serviceID
)
7235 SCNetworkInterfacePrivateRef oldPrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7236 SCNetworkInterfacePrivateRef newPrivate
;
7238 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
7239 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
7241 if (interface
== kSCNetworkInterfaceIPv4
) {
7242 return (SCNetworkInterfacePrivateRef
)CFRetain(interface
);
7245 newPrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, prefs
, serviceID
);
7246 newPrivate
->interface_type
= oldPrivate
->interface_type
;
7247 if (oldPrivate
->interface
!= NULL
) {
7248 newPrivate
->interface
= (SCNetworkInterfaceRef
)__SCNetworkInterfaceCreateCopy(NULL
, // allocator
7249 oldPrivate
->interface
, // interface
7250 prefs
, // [new] prefs
7251 serviceID
); // [new] serviceID
7253 if (oldPrivate
->name
!= NULL
) {
7254 newPrivate
->name
= CFRetain(oldPrivate
->name
);
7256 if (oldPrivate
->prefix
!= NULL
) {
7257 newPrivate
->prefix
= CFRetain(oldPrivate
->prefix
);
7259 if (oldPrivate
->localized_name
!= NULL
) {
7260 newPrivate
->localized_name
= CFRetain(oldPrivate
->localized_name
);
7262 newPrivate
->localized_key
= oldPrivate
->localized_key
;
7263 if (oldPrivate
->localized_arg1
!= NULL
) {
7264 newPrivate
->localized_arg1
= CFRetain(oldPrivate
->localized_arg1
);
7266 if (oldPrivate
->localized_arg2
!= NULL
) {
7267 newPrivate
->localized_arg2
= CFRetain(oldPrivate
->localized_arg2
);
7269 if (oldPrivate
->unsaved
!= NULL
) {
7270 newPrivate
->unsaved
= CFDictionaryCreateMutableCopy(NULL
, 0, oldPrivate
->unsaved
);
7272 if (oldPrivate
->entity_device
!= NULL
) {
7273 newPrivate
->entity_device
= CFRetain(oldPrivate
->entity_device
);
7275 if (oldPrivate
->entity_device_unique
!= NULL
) {
7276 newPrivate
->entity_device_unique
= CFRetain(oldPrivate
->entity_device_unique
);
7278 newPrivate
->entity_type
= oldPrivate
->entity_type
;
7279 newPrivate
->entity_subtype
= oldPrivate
->entity_subtype
;
7280 if (oldPrivate
->supported_interface_types
!= NULL
) {
7281 newPrivate
->supported_interface_types
= CFArrayCreateMutableCopy(NULL
, 0, oldPrivate
->supported_interface_types
);
7283 if (oldPrivate
->supported_protocol_types
!= NULL
) {
7284 newPrivate
->supported_protocol_types
= CFArrayCreateMutableCopy(NULL
, 0, oldPrivate
->supported_protocol_types
);
7286 if (oldPrivate
->address
!= NULL
) {
7287 newPrivate
->address
= CFRetain(oldPrivate
->address
);
7289 newPrivate
->builtin
= oldPrivate
->builtin
;
7290 if (oldPrivate
->configurationAction
!= NULL
) {
7291 newPrivate
->configurationAction
= CFRetain(oldPrivate
->configurationAction
);
7293 newPrivate
->hidden
= oldPrivate
->hidden
;
7294 if (oldPrivate
->location
!= NULL
) {
7295 newPrivate
->location
= CFRetain(oldPrivate
->location
);
7297 if (oldPrivate
->path
!= NULL
) {
7298 newPrivate
->path
= CFRetain(oldPrivate
->path
);
7300 newPrivate
->entryID
= oldPrivate
->entryID
;
7301 if (oldPrivate
->overrides
!= NULL
) {
7302 newPrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, oldPrivate
->overrides
);
7304 newPrivate
->modemIsV92
= oldPrivate
->modemIsV92
;
7305 if (oldPrivate
->type
!= NULL
) {
7306 newPrivate
->type
= CFRetain(oldPrivate
->type
);
7308 if (oldPrivate
->unit
!= NULL
) {
7309 newPrivate
->unit
= CFRetain(oldPrivate
->unit
);
7311 if (oldPrivate
->usb
.name
!= NULL
) {
7312 newPrivate
->usb
.name
= CFRetain(oldPrivate
->usb
.name
);
7314 if (oldPrivate
->usb
.vid
!= NULL
) {
7315 newPrivate
->usb
.vid
= CFRetain(oldPrivate
->usb
.vid
);
7317 if (oldPrivate
->usb
.pid
!= NULL
) {
7318 newPrivate
->usb
.pid
= CFRetain(oldPrivate
->usb
.pid
);
7320 newPrivate
->sort_order
= oldPrivate
->sort_order
;
7322 newPrivate
->supportsBond
= oldPrivate
->supportsBond
;
7323 if (oldPrivate
->bond
.interfaces
!= NULL
) {
7324 newPrivate
->bond
.interfaces
= CFRetain(oldPrivate
->bond
.interfaces
);
7326 if (oldPrivate
->bond
.mode
!= NULL
) {
7327 newPrivate
->bond
.mode
= CFRetain(oldPrivate
->bond
.mode
);
7329 if (oldPrivate
->bond
.options
!= NULL
) {
7330 newPrivate
->bond
.options
= CFRetain(oldPrivate
->bond
.options
);
7333 newPrivate
->supportsBridge
= oldPrivate
->supportsBridge
;
7334 if (oldPrivate
->bridge
.interfaces
!= NULL
) {
7335 newPrivate
->bridge
.interfaces
= CFRetain(oldPrivate
->bridge
.interfaces
);
7337 if (oldPrivate
->bridge
.options
!= NULL
) {
7338 newPrivate
->bridge
.options
= CFRetain(oldPrivate
->bridge
.options
);
7341 newPrivate
->supportsVLAN
= oldPrivate
->supportsVLAN
;
7342 if (oldPrivate
->vlan
.interface
!= NULL
) {
7343 newPrivate
->vlan
.interface
= CFRetain(oldPrivate
->vlan
.interface
);
7345 if (oldPrivate
->vlan
.tag
!= NULL
) {
7346 newPrivate
->vlan
.tag
= CFRetain(oldPrivate
->vlan
.tag
);
7348 if (oldPrivate
->vlan
.options
!= NULL
) {
7349 newPrivate
->vlan
.options
= CFRetain(oldPrivate
->vlan
.options
);
7358 __SCNetworkInterfaceCopyDeepConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
)
7360 CFMutableArrayRef configs
;
7362 configs
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
7364 while (interface
!= NULL
) {
7365 CFStringRef defaultType
;
7366 CFMutableDictionaryRef interfaceConfiguration
;
7368 interfaceConfiguration
= CFDictionaryCreateMutable(NULL
,
7370 &kCFTypeDictionaryKeyCallBacks
,
7371 &kCFTypeDictionaryValueCallBacks
);
7373 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
7374 if (defaultType
!= NULL
) {
7375 CFDictionaryRef config
;
7376 CFArrayRef extendedTypes
;
7379 config
= __SCNetworkInterfaceGetConfiguration(interface
, defaultType
);
7381 config
= __SCNetworkInterfaceGetDefaultConfiguration(set
, interface
);
7383 if (config
== NULL
) {
7384 config
= (CFDictionaryRef
)kCFNull
;
7386 CFDictionarySetValue(interfaceConfiguration
, defaultType
, config
);
7388 extendedTypes
= extendedConfigurationTypes(interface
);
7389 if (extendedTypes
!= NULL
) {
7393 n
= CFArrayGetCount(extendedTypes
);
7394 for (i
= 0; i
< n
; i
++) {
7395 CFStringRef extendedType
;
7397 extendedType
= CFArrayGetValueAtIndex(extendedTypes
, i
);
7398 config
= __SCNetworkInterfaceGetConfiguration(interface
, extendedType
);
7399 if (config
== NULL
) {
7400 config
= (CFDictionaryRef
)kCFNull
;
7402 CFDictionarySetValue(interfaceConfiguration
, extendedType
, config
);
7405 CFRelease(extendedTypes
);
7409 CFArrayAppendValue(configs
, interfaceConfiguration
);
7410 CFRelease(interfaceConfiguration
);
7412 interface
= SCNetworkInterfaceGetInterface(interface
);
7419 __private_extern__ Boolean
7420 __SCNetworkInterfaceIsMember(SCPreferencesRef prefs
, SCNetworkInterfaceRef interface
)
7422 CFArrayRef interfaces
;
7423 Boolean match
= FALSE
;
7424 CFMutableSetRef members
;
7426 members
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
7428 #if !TARGET_OS_IPHONE
7429 // add Bond [member] interfaces
7430 interfaces
= SCBondInterfaceCopyAll(prefs
);
7431 if (interfaces
!= NULL
) {
7432 __SCBondInterfaceListCollectMembers(interfaces
, members
);
7433 CFRelease(interfaces
);
7435 #endif // !TARGET_OS_IPHONE
7437 // add Bridge [member] interfaces
7438 interfaces
= SCBridgeInterfaceCopyAll(prefs
);
7439 if (interfaces
!= NULL
) {
7440 __SCBridgeInterfaceListCollectMembers(interfaces
, members
);
7441 CFRelease(interfaces
);
7444 if (CFSetGetCount(members
) == 0) {
7448 while (interface
!= NULL
) {
7449 match
= CFSetContainsValue(members
, interface
);
7451 // if the interface is a member of an
7452 // Ethernet Bond or Bridge
7456 interface
= SCNetworkInterfaceGetInterface(interface
);
7468 __SCNetworkInterfaceSetDeepConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
, CFArrayRef configs
)
7472 for (i
= 0; interface
!= NULL
; i
++) {
7473 CFStringRef defaultType
;
7474 CFDictionaryRef interfaceConfiguration
;
7476 interfaceConfiguration
= (configs
!= NULL
) ? CFArrayGetValueAtIndex(configs
, i
) : NULL
;
7478 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
7479 if (defaultType
!= NULL
) {
7480 CFDictionaryRef config
;
7481 CFArrayRef extendedTypes
;
7483 config
= (interfaceConfiguration
!= NULL
) ? CFDictionaryGetValue(interfaceConfiguration
, defaultType
)
7485 if (config
== (CFDictionaryRef
)kCFNull
) {
7489 // if service is not associated with the set
7490 if (!__SCNetworkInterfaceSetConfiguration(interface
, defaultType
, config
, TRUE
)) {
7491 SCLog(TRUE
, LOG_DEBUG
,
7492 CFSTR("__SCNetworkInterfaceSetDeepConfiguration __SCNetworkInterfaceSetConfiguration() failed, interface=%@, type=%@"),
7497 // apply default configuration to this set
7498 if (!__SCNetworkInterfaceSetDefaultConfiguration(set
, interface
, defaultType
, config
, TRUE
)) {
7499 SCLog(TRUE
, LOG_DEBUG
,
7500 CFSTR("__SCNetworkInterfaceSetDeepConfiguration __SCNetworkInterfaceSetDefaultConfiguration() failed, interface=%@, type=%@"),
7506 extendedTypes
= extendedConfigurationTypes(interface
);
7507 if (extendedTypes
!= NULL
) {
7511 n
= CFArrayGetCount(extendedTypes
);
7512 for (j
= 0; j
< n
; j
++) {
7513 CFStringRef extendedType
;
7515 extendedType
= CFArrayGetValueAtIndex(extendedTypes
, j
);
7516 config
= (interfaceConfiguration
!= NULL
) ? CFDictionaryGetValue(interfaceConfiguration
, extendedType
)
7518 if (config
== (CFDictionaryRef
)kCFNull
) {
7521 if (!__SCNetworkInterfaceSetConfiguration(interface
, extendedType
, config
, TRUE
)) {
7522 SCLog(TRUE
, LOG_DEBUG
,
7523 CFSTR("__SCNetworkInterfaceSetDeepConfiguration __SCNetworkInterfaceSetConfiguration() failed, interface=%@, type=%@"),
7529 CFRelease(extendedTypes
);
7533 interface
= SCNetworkInterfaceGetInterface(interface
);
7540 SCNetworkInterfaceRef
7541 _SCNetworkInterfaceCopyActive(SCDynamicStoreRef store
, CFStringRef bsdName
)
7543 SCNetworkInterfaceRef interface
;
7545 interface
= _SCNetworkInterfaceCreateWithBSDName(NULL
, bsdName
, kIncludeAllVirtualInterfaces
);
7546 if (interface
== NULL
) {
7550 if (store
!= NULL
) {
7551 SCNetworkInterfacePrivateRef interfacePrivate
=
7552 (SCNetworkInterfacePrivateRef
)interface
;
7555 interfacePrivate
->store
= store
;
7562 #if !TARGET_IPHONE_SIMULATOR
7563 SCNetworkServicePrimaryRank
7564 SCNetworkInterfaceGetPrimaryRank(SCNetworkInterfaceRef interface
)
7566 IPMonitorControlRef control
;
7567 SCNetworkInterfacePrivateRef interfacePrivate
=
7568 (SCNetworkInterfacePrivateRef
)interface
;
7569 SCNetworkServicePrimaryRank rank
= kSCNetworkServicePrimaryRankDefault
;
7571 control
= interfacePrivate
->IPMonitorControl
;
7572 if (control
!= NULL
) {
7575 ifName
= SCNetworkInterfaceGetBSDName(interface
);
7576 if (ifName
!= NULL
) {
7577 rank
= IPMonitorControlGetInterfacePrimaryRank(control
,
7581 _SCErrorSet(kSCStatusInvalidArgument
);
7588 SCNetworkInterfaceSetPrimaryRank(SCNetworkInterfaceRef interface
,
7589 SCNetworkServicePrimaryRank newRank
)
7591 IPMonitorControlRef control
;
7592 SCNetworkInterfacePrivateRef interfacePrivate
=
7593 (SCNetworkInterfacePrivateRef
)interface
;
7596 ifName
= SCNetworkInterfaceGetBSDName(interface
);
7597 if (ifName
== NULL
) {
7598 _SCErrorSet(kSCStatusInvalidArgument
);
7601 control
= interfacePrivate
->IPMonitorControl
;
7602 if (control
== NULL
) {
7603 control
= IPMonitorControlCreate();
7604 if (control
== NULL
) {
7605 _SCErrorSet(kSCStatusFailed
);
7608 interfacePrivate
->IPMonitorControl
= control
;
7610 return IPMonitorControlSetInterfacePrimaryRank(control
,
7614 #else // !TARGET_IPHONE_SIMULATOR
7616 SCNetworkServicePrimaryRank
7617 SCNetworkInterfaceGetPrimaryRank(SCNetworkInterfaceRef interface
)
7619 return (kSCNetworkServicePrimaryRankDefault
);
7623 SCNetworkInterfaceSetPrimaryRank(SCNetworkInterfaceRef interface
,
7624 SCNetworkServicePrimaryRank newRank
)
7626 _SCErrorSet(kSCStatusInvalidArgument
);
7630 #endif // !TARGET_IPHONE_SIMULATOR
7634 CFArrayRef
// SCNetworkInterfaceRef
7635 __SCNetworkInterfaceCopyStoredWithPreferences (SCPreferencesRef ni_prefs
)
7637 CFMutableArrayRef interfaceList
= NULL
;
7639 SCNetworkInterfaceRef interfaceNamer
= NULL
;
7640 CFStringRef defaultNetworkInterfacePath
= NULL
;
7642 /* initialize runtime */
7643 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
7645 if (ni_prefs
== NULL
) {
7646 defaultNetworkInterfacePath
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@/%@"), PREFS_DEFAULT_DIR
, NETWORK_INTERFACES_PREFS
);
7647 ni_prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath
);
7650 if_list
= SCPreferencesGetValue(ni_prefs
, INTERFACES
);
7652 if (isA_CFArray(if_list
) != NULL
) {
7654 CFIndex n
= CFArrayGetCount(if_list
);
7656 interfaceList
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
7657 for (i
= 0; i
< n
; i
++) {
7658 CFDictionaryRef dict
;
7660 dict
= CFArrayGetValueAtIndex(if_list
, i
);
7661 if (isA_CFDictionary(dict
) != NULL
) {
7662 interfaceNamer
= __SCNetworkInterfaceCreateWithStorageEntity(NULL
, dict
, ni_prefs
);
7664 if (interfaceNamer
!= NULL
) {
7665 CFArrayAppendValue(interfaceList
, interfaceNamer
);
7666 CFRelease(interfaceNamer
);
7672 if (defaultNetworkInterfacePath
!= NULL
) {
7673 CFRelease(defaultNetworkInterfacePath
);
7674 // prefs were created in the function, and hence need to be released
7675 CFRelease(ni_prefs
);
7677 return interfaceList
;
7683 __SCNetworkInterfaceSaveStoredWithPreferences(SCPreferencesRef prefs
, CFArrayRef interfacesToSave
)
7685 CFStringRef defaultNetworkInterfacePath
= NULL
;
7686 Boolean success
= FALSE
;
7688 if (prefs
== NULL
) { // TODO: Get the default preferences on the system
7689 defaultNetworkInterfacePath
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@%@"), PREFS_DEFAULT_DIR
, NETWORK_INTERFACES_PREFS
);
7690 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath
);
7693 if (isA_CFArray(interfacesToSave
) == NULL
) {
7694 SCLog(TRUE
, LOG_DEBUG
, CFSTR("interfacesToSave is NULL or not of correct type"));
7697 SCPreferencesSetValue(prefs
, INTERFACES
, interfacesToSave
);
7700 if (defaultNetworkInterfacePath
!= NULL
) {
7701 CFRelease(defaultNetworkInterfacePath
);
7702 // prefs were created in the function, and hence need to be released
7710 SCNetworkInterfaceRef
7711 __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(CFAllocatorRef allocator
, SCPreferencesRef ni_prefs
, CFStringRef bsdName
)
7714 SCNetworkInterfaceRef interface
= NULL
;
7715 CFStringRef defaultNetworkInterfacePath
;
7717 /* initialize runtime */
7718 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
7720 if (ni_prefs
== NULL
) {
7721 defaultNetworkInterfacePath
= CFStringCreateWithFormat(allocator
, NULL
, CFSTR("%@/%@"), PREFS_DEFAULT_DIR
, NETWORK_INTERFACES_PREFS
);
7722 ni_prefs
= SCPreferencesCreate(allocator
, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath
);
7723 CFRelease(defaultNetworkInterfacePath
);
7729 if_list
= SCPreferencesGetValue(ni_prefs
, INTERFACES
);
7731 if (isA_CFArray(if_list
) != NULL
) {
7733 CFIndex count
= CFArrayGetCount(if_list
);
7735 for (idx
= 0; idx
< count
; idx
++) {
7736 CFDictionaryRef dict
;
7737 CFStringRef tmp_bsdName
;
7739 dict
= CFArrayGetValueAtIndex(if_list
, idx
);
7740 if (isA_CFDictionary(dict
) == NULL
) {
7744 tmp_bsdName
= CFDictionaryGetValue(dict
, CFSTR(kSCNetworkInterfaceBSDName
));
7745 if (tmp_bsdName
== NULL
) {
7748 if (CFEqual(bsdName
, tmp_bsdName
) == TRUE
) {
7749 interface
= __SCNetworkInterfaceCreateWithStorageEntity(allocator
, dict
, ni_prefs
);
7755 CFRelease(ni_prefs
);
7761 __SCNetworkInterfaceCreateMappingUsingBSDName(CFArrayRef interfaces
)
7763 CFMutableDictionaryRef mappingBSDToInterface
= NULL
;
7764 CFStringRef bsdName
= NULL
;
7765 SCNetworkInterfaceRef interface
= NULL
;
7768 count
= CFArrayGetCount(interfaces
);
7771 SCLog(TRUE
, LOG_DEBUG
, CFSTR("__SCNetworkInterfaceCreateMappingUsingBSDName: Interface count is 0"));
7774 mappingBSDToInterface
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
7776 for (CFIndex idx
= 0; idx
< count
; idx
++) {
7777 interface
= (SCNetworkInterfaceRef
) CFArrayGetValueAtIndex(interfaces
, idx
);
7779 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
7780 if (isA_CFString(bsdName
) == NULL
) {
7781 SCLog(TRUE
, LOG_DEBUG
, CFSTR("__SCNetworkInterfaceCreateMappingUsingBSDName: BSDName is NULL or not of the correct type"));
7784 CFDictionaryAddValue(mappingBSDToInterface
, bsdName
, interface
);
7786 if (CFDictionaryGetCount(mappingBSDToInterface
) == 0) {
7787 CFRelease(mappingBSDToInterface
);
7788 mappingBSDToInterface
= NULL
;
7789 SCLog(TRUE
, LOG_DEBUG
, CFSTR("__SCNetworkInterfaceCreateMappingUsingBSDName: Setting mappingBSDToInterface to NULL since it doesn't contain any data"));
7792 return mappingBSDToInterface
;