2 * Copyright (c) 2004-2007 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 <CoreFoundation/CoreFoundation.h>
37 #include <CoreFoundation/CFRuntime.h>
38 #include <SystemConfiguration/SystemConfiguration.h>
39 #include "SCNetworkConfigurationInternal.h"
40 #include <SystemConfiguration/SCValidation.h>
41 #include <SystemConfiguration/SCPrivate.h>
42 #include <SystemConfiguration/BondConfiguration.h>
43 #include <SystemConfiguration/VLANConfiguration.h>
44 #include "SCPreferencesInternal.h"
45 #include "SCHelper_client.h"
47 #include <EAP8021X/EAPClientProperties.h>
49 #include <IOKit/IOKitLib.h>
50 #include <IOKit/IOCFBundle.h>
51 #include <IOKit/IOBSD.h>
52 #include <IOKit/network/IONetworkController.h>
53 #include <IOKit/network/IONetworkInterface.h>
54 #include <IOKit/network/IOEthernetInterface.h> // for kIOEthernetInterfaceClass
55 #include <IOKit/serial/IOSerialKeys.h>
56 #include <IOKit/storage/IOStorageDeviceCharacteristics.h>
57 #include "dy_framework.h"
59 #ifndef kIODeviceSupportsHoldKey
60 #define kIODeviceSupportsHoldKey "V92Modem"
64 #include <mach/mach.h>
66 #include <net/if_types.h>
67 #include <net/route.h>
68 #include <sys/param.h>
69 #include <sys/types.h>
70 #include <sys/socket.h>
72 #include <sys/sysctl.h>
74 #include <NSSystemDirectories.h>
77 #if MAC_OS_X_VERSION_MIN_REQUIRED < 1040
78 #error MAC_OS_X_VERSION_MIN_REQUIRED < 1040, Check MACOSX_DEPLOYMENT_TARGET
82 static CFStringRef
copy_interface_string (CFBundleRef bundle
, CFStringRef key
, Boolean localized
);
83 static CFStringRef
__SCNetworkInterfaceCopyDescription (CFTypeRef cf
);
84 static void __SCNetworkInterfaceDeallocate (CFTypeRef cf
);
85 static Boolean
__SCNetworkInterfaceEqual (CFTypeRef cf1
, CFTypeRef cf2
);
86 static CFHashCode
__SCNetworkInterfaceHash (CFTypeRef cf
);
108 const CFStringRef kSCNetworkInterfaceType6to4
= CFSTR("6to4");
109 const CFStringRef kSCNetworkInterfaceTypeBluetooth
= CFSTR("Bluetooth");
110 const CFStringRef kSCNetworkInterfaceTypeBond
= CFSTR("Bond");
111 const CFStringRef kSCNetworkInterfaceTypeEthernet
= CFSTR("Ethernet");
112 const CFStringRef kSCNetworkInterfaceTypeFireWire
= CFSTR("FireWire");
113 const CFStringRef kSCNetworkInterfaceTypeIEEE80211
= CFSTR("IEEE80211"); // IEEE 802.11, AirPort
114 const CFStringRef kSCNetworkInterfaceTypeIrDA
= CFSTR("IrDA");
115 const CFStringRef kSCNetworkInterfaceTypeL2TP
= CFSTR("L2TP");
116 const CFStringRef kSCNetworkInterfaceTypeModem
= CFSTR("Modem");
117 const CFStringRef kSCNetworkInterfaceTypePPP
= CFSTR("PPP");
118 const CFStringRef kSCNetworkInterfaceTypePPTP
= CFSTR("PPTP");
119 const CFStringRef kSCNetworkInterfaceTypeSerial
= CFSTR("Serial");
120 const CFStringRef kSCNetworkInterfaceTypeVLAN
= CFSTR("VLAN");
121 const CFStringRef kSCNetworkInterfaceTypeWWAN
= CFSTR("WWAN");
123 const CFStringRef kSCNetworkInterfaceTypeIPv4
= CFSTR("IPv4");
125 static SCNetworkInterfacePrivate __kSCNetworkInterfaceIPv4
= {
126 INIT_CFRUNTIME_BASE(NULL
, 0, 0x0080), // cfBase
127 NULL
, // interface type
129 NULL
, // localized name
130 NULL
, // localization key
131 NULL
, // localization arg1
132 NULL
, // localization arg2
133 NULL
, // [layered] interface
137 NULL
, // entity_device
139 NULL
, // entity_subtype
140 NULL
, // supported_interface_types
141 NULL
, // supported_protocol_types
143 NULL
, // addressString
149 FALSE
, // supportsBond
150 FALSE
, // supportsVLAN
153 kSortUnknown
, // sort_order
154 { NULL
, NULL
}, // bond { interfaces, options }
155 { NULL
, NULL
, NULL
} // vlan { interface, tag, options }
158 const SCNetworkInterfaceRef kSCNetworkInterfaceIPv4
= (SCNetworkInterfaceRef
)&__kSCNetworkInterfaceIPv4
;
161 #pragma mark SCNetworkInterface configuration details
170 #define doAppleTalk 1<<0
174 #define doProxies 1<<4
177 static const struct {
178 const CFStringRef
*interface_type
;
179 const CFStringRef
*entity_hardware
;
180 Boolean per_interface_config
;
181 uint32_t supported_interfaces
;
182 const CFStringRef
*ppp_subtype
;
183 uint32_t supported_protocols
;
184 } configurations
[] = {
185 // interface type entity_hardware if config? interface types PPP sub-type interface protocols
186 // ===================================== ================= ========== ======================= ======================================= =========================================
187 { &kSCNetworkInterfaceType6to4
, &kSCEntNet6to4
, FALSE
, doNone
, NULL
, doIPv6
},
188 { &kSCNetworkInterfaceTypeBluetooth
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
189 { &kSCNetworkInterfaceTypeBond
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doAppleTalk
|doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
190 { &kSCNetworkInterfaceTypeEthernet
, &kSCEntNetEthernet
, TRUE
, doPPP
, &kSCValNetInterfaceSubTypePPPoE
, doAppleTalk
|doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
191 { &kSCNetworkInterfaceTypeFireWire
, &kSCEntNetFireWire
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
192 { &kSCNetworkInterfaceTypeIEEE80211
, &kSCEntNetAirPort
, TRUE
, doPPP
, &kSCValNetInterfaceSubTypePPPoE
, doAppleTalk
|doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
193 { &kSCNetworkInterfaceTypeIrDA
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
194 { &kSCNetworkInterfaceTypeL2TP
, NULL
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypeL2TP
, doNone
},
195 { &kSCNetworkInterfaceTypeModem
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
196 { &kSCNetworkInterfaceTypePPP
, &kSCEntNetPPP
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
197 { &kSCNetworkInterfaceTypePPTP
, NULL
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPTP
, doNone
},
198 { &kSCNetworkInterfaceTypeSerial
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
199 { &kSCNetworkInterfaceTypeVLAN
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doAppleTalk
|doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
200 { &kSCNetworkInterfaceTypeWWAN
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
201 // ===================================== ================= ========== ======================= ======================================= =========================================
202 { &kSCNetworkInterfaceTypeIPv4
, NULL
, FALSE
, do6to4
|doL2TP
|doPPTP
, NULL
, doNone
}
206 #define NETWORKINTERFACE_LOCALIZATIONS CFSTR("NetworkInterface")
207 static CFBundleRef bundle
= NULL
;
210 static CFTypeID __kSCNetworkInterfaceTypeID
= _kCFRuntimeNotATypeID
;
213 static const CFRuntimeClass __SCNetworkInterfaceClass
= {
215 "SCNetworkInterface", // className
218 __SCNetworkInterfaceDeallocate
, // dealloc
219 __SCNetworkInterfaceEqual
, // equal
220 __SCNetworkInterfaceHash
, // hash
221 NULL
, // copyFormattingDesc
222 __SCNetworkInterfaceCopyDescription
// copyDebugDesc
226 static pthread_once_t initialized
= PTHREAD_ONCE_INIT
;
227 static pthread_once_t iokit_quiet
= PTHREAD_ONCE_INIT
;
230 static mach_port_t masterPort
= MACH_PORT_NULL
;
234 __SCNetworkInterfaceCopyDescription(CFTypeRef cf
)
236 CFAllocatorRef allocator
= CFGetAllocator(cf
);
237 CFMutableStringRef result
;
238 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
240 result
= CFStringCreateMutable(allocator
, 0);
241 CFStringAppendFormat(result
, NULL
, CFSTR("<SCNetworkInterface %p [%p]> {"), cf
, allocator
);
242 CFStringAppendFormat(result
, NULL
, CFSTR("type = %@"), interfacePrivate
->interface_type
);
243 CFStringAppendFormat(result
, NULL
, CFSTR(", entity_device = %@"), interfacePrivate
->entity_device
);
244 CFStringAppendFormat(result
, NULL
, CFSTR(", entity_type = %@"), interfacePrivate
->entity_type
);
245 if (interfacePrivate
->entity_subtype
!= NULL
) {
246 CFStringAppendFormat(result
, NULL
, CFSTR(" / %@"), interfacePrivate
->entity_subtype
);
248 if (interfacePrivate
->name
!= NULL
) {
249 CFStringAppendFormat(result
, NULL
, CFSTR(", name = %@"), interfacePrivate
->name
);
251 if (interfacePrivate
->localized_name
!= NULL
) {
252 CFStringAppendFormat(result
, NULL
, CFSTR(", name(l) = %@"), interfacePrivate
->localized_name
);
254 if (interfacePrivate
->localized_key
!= NULL
) {
255 CFStringAppendFormat(result
, NULL
, CFSTR(", name(k) = \"%@\""), interfacePrivate
->localized_key
);
256 if (interfacePrivate
->localized_arg1
!= NULL
) {
257 CFStringAppendFormat(result
, NULL
, CFSTR("+\"%@\""), interfacePrivate
->localized_arg1
);
259 if (interfacePrivate
->localized_arg2
!= NULL
) {
260 CFStringAppendFormat(result
, NULL
, CFSTR("+\"%@\""), interfacePrivate
->localized_arg2
);
264 if (interfacePrivate
->address
!= NULL
) {
269 CFStringAppendFormat(result
, NULL
, CFSTR(", address = 0x"));
271 data
= CFDataGetBytePtr(interfacePrivate
->address
);
272 dataLen
= CFDataGetLength(interfacePrivate
->address
);
273 for (i
= 0; i
< dataLen
; i
++) {
274 CFStringAppendFormat(result
, NULL
, CFSTR("%02x"), data
[i
]);
277 CFStringAppendFormat(result
, NULL
, CFSTR(", builtin = %s"), interfacePrivate
->builtin
? "TRUE" : "FALSE");
278 if (interfacePrivate
->modemIsV92
) {
279 CFStringAppendFormat(result
, NULL
, CFSTR(", v.92"));
281 if (interfacePrivate
->location
!= NULL
) {
282 CFStringAppendFormat(result
, NULL
, CFSTR(", location = %@"), interfacePrivate
->location
);
284 if (interfacePrivate
->type
!= NULL
) {
285 CFStringAppendFormat(result
, NULL
, CFSTR(", type = %@"), interfacePrivate
->type
);
287 if (interfacePrivate
->unit
!= NULL
) {
288 CFStringAppendFormat(result
, NULL
, CFSTR(", unit = %@"), interfacePrivate
->unit
);
290 if (interfacePrivate
->path
!= NULL
) {
291 CFStringAppendFormat(result
, NULL
, CFSTR(", path = %@"), interfacePrivate
->path
);
293 if (interfacePrivate
->overrides
!= NULL
) {
294 CFStringAppendFormat(result
, NULL
, CFSTR(", overrides = %p"), interfacePrivate
->overrides
);
296 CFStringAppendFormat(result
, NULL
, CFSTR(", order = %d"), interfacePrivate
->sort_order
);
297 if (interfacePrivate
->prefs
!= NULL
) {
298 CFStringAppendFormat(result
, NULL
, CFSTR(", prefs = %p"), interfacePrivate
->prefs
);
300 if (interfacePrivate
->serviceID
!= NULL
) {
301 CFStringAppendFormat(result
, NULL
, CFSTR(", service = %@"), interfacePrivate
->serviceID
);
303 if (interfacePrivate
->interface
!= NULL
) {
304 CFStringAppendFormat(result
, NULL
, CFSTR(", interface = %@"), interfacePrivate
->interface
);
306 if (interfacePrivate
->unsaved
!= NULL
) {
307 CFStringAppendFormat(result
, NULL
, CFSTR(", unsaved = %@"), interfacePrivate
->unsaved
);
309 if (interfacePrivate
->bond
.interfaces
!= NULL
) {
313 n
= CFArrayGetCount(interfacePrivate
->bond
.interfaces
);
314 for (i
= 0; i
< n
; i
++) {
315 SCNetworkInterfaceRef member
;
317 member
= CFArrayGetValueAtIndex(interfacePrivate
->bond
.interfaces
, i
);
318 CFStringAppendFormat(result
, NULL
,
320 (i
== 0) ? ", interfaces = " : ", ",
321 SCNetworkInterfaceGetBSDName(member
));
324 if (interfacePrivate
->bond
.mode
!= NULL
) {
325 CFStringAppendFormat(result
, NULL
, CFSTR(", mode = %@"), interfacePrivate
->bond
.mode
);
327 if (interfacePrivate
->bond
.options
!= NULL
) {
328 CFStringAppendFormat(result
, NULL
, CFSTR(", options = %@"), interfacePrivate
->bond
.options
);
330 if (interfacePrivate
->bond
.mode
!= NULL
) {
331 CFStringAppendFormat(result
, NULL
, CFSTR(", mode = %@"), interfacePrivate
->bond
.mode
);
333 if (interfacePrivate
->vlan
.interface
!= NULL
) {
334 CFStringAppendFormat(result
, NULL
,
335 CFSTR(", interface = %@"),
336 SCNetworkInterfaceGetBSDName(interfacePrivate
->vlan
.interface
));
338 if (interfacePrivate
->vlan
.tag
!= NULL
) {
339 CFStringAppendFormat(result
, NULL
, CFSTR(", tag = %@"), interfacePrivate
->vlan
.tag
);
341 if (interfacePrivate
->vlan
.options
!= NULL
) {
342 CFStringAppendFormat(result
, NULL
, CFSTR(", options = %@"), interfacePrivate
->vlan
.options
);
344 CFStringAppendFormat(result
, NULL
, CFSTR("}"));
351 __SCNetworkInterfaceDeallocate(CFTypeRef cf
)
353 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
355 /* release resources */
357 if (interfacePrivate
->interface
!= NULL
)
358 CFRelease(interfacePrivate
->interface
);
360 if (interfacePrivate
->name
!= NULL
)
361 CFRelease(interfacePrivate
->name
);
363 if (interfacePrivate
->localized_name
!= NULL
)
364 CFRelease(interfacePrivate
->localized_name
);
366 if (interfacePrivate
->localized_arg1
!= NULL
)
367 CFRelease(interfacePrivate
->localized_arg1
);
369 if (interfacePrivate
->localized_arg2
!= NULL
)
370 CFRelease(interfacePrivate
->localized_arg2
);
372 if (interfacePrivate
->prefs
!= NULL
)
373 CFRelease(interfacePrivate
->prefs
);
375 if (interfacePrivate
->serviceID
!= NULL
)
376 CFRelease(interfacePrivate
->serviceID
);
378 if (interfacePrivate
->unsaved
!= NULL
)
379 CFRelease(interfacePrivate
->unsaved
);
381 if (interfacePrivate
->entity_device
!= NULL
)
382 CFRelease(interfacePrivate
->entity_device
);
384 if (interfacePrivate
->supported_interface_types
!= NULL
)
385 CFRelease(interfacePrivate
->supported_interface_types
);
387 if (interfacePrivate
->supported_protocol_types
!= NULL
)
388 CFRelease(interfacePrivate
->supported_protocol_types
);
390 if (interfacePrivate
->address
!= NULL
)
391 CFRelease(interfacePrivate
->address
);
393 if (interfacePrivate
->addressString
!= NULL
)
394 CFRelease(interfacePrivate
->addressString
);
396 if (interfacePrivate
->location
!= NULL
)
397 CFRelease(interfacePrivate
->location
);
399 if (interfacePrivate
->path
!= NULL
)
400 CFRelease(interfacePrivate
->path
);
402 if (interfacePrivate
->overrides
!= NULL
)
403 CFRelease(interfacePrivate
->overrides
);
405 if (interfacePrivate
->type
!= NULL
)
406 CFRelease(interfacePrivate
->type
);
408 if (interfacePrivate
->unit
!= NULL
)
409 CFRelease(interfacePrivate
->unit
);
411 if (interfacePrivate
->bond
.interfaces
!= NULL
)
412 CFRelease(interfacePrivate
->bond
.interfaces
);
414 if (interfacePrivate
->bond
.mode
!= NULL
)
415 CFRelease(interfacePrivate
->bond
.mode
);
417 if (interfacePrivate
->bond
.options
!= NULL
)
418 CFRelease(interfacePrivate
->bond
.options
);
420 if (interfacePrivate
->vlan
.interface
!= NULL
)
421 CFRelease(interfacePrivate
->vlan
.interface
);
423 if (interfacePrivate
->vlan
.tag
!= NULL
)
424 CFRelease(interfacePrivate
->vlan
.tag
);
426 if (interfacePrivate
->vlan
.options
!= NULL
)
427 CFRelease(interfacePrivate
->vlan
.options
);
434 __SCNetworkInterfaceEqual(CFTypeRef cf1
, CFTypeRef cf2
)
436 SCNetworkInterfacePrivateRef if1
= (SCNetworkInterfacePrivateRef
)cf1
;
437 SCNetworkInterfacePrivateRef if2
= (SCNetworkInterfacePrivateRef
)cf2
;
442 if (!CFEqual(if1
->interface_type
, if2
->interface_type
)) {
443 return FALSE
; // if not the same interface type
446 if (!_SC_CFEqual(if1
->entity_device
, if2
->entity_device
)) {
447 return FALSE
; // if not the same device
450 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeBond
)) {
451 if (!_SC_CFEqual(if1
->bond
.interfaces
, if2
->bond
.interfaces
)) {
452 return FALSE
; // if not the same interfaces
454 if (!_SC_CFEqual(if1
->bond
.mode
, if2
->bond
.mode
)) {
455 return FALSE
; // if not the same mode
459 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeVLAN
)) {
460 if (!_SC_CFEqual(if1
->vlan
.interface
, if2
->vlan
.interface
)) {
461 return FALSE
; // if not the same physical interface
463 if (!_SC_CFEqual(if1
->vlan
.tag
, if2
->vlan
.tag
)) {
464 return FALSE
; // if not the same tag
468 if (!CFEqual(if1
->interface
, if2
->interface
)) {
469 return FALSE
; // if not the same layering
477 __SCNetworkInterfaceHash(CFTypeRef cf
)
479 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
481 if (interfacePrivate
->entity_device
!= NULL
) {
482 return CFHash(interfacePrivate
->entity_device
);
490 __SCNetworkInterfaceInitialize(void)
495 __kSCNetworkInterfaceTypeID
= _CFRuntimeRegisterClass(&__SCNetworkInterfaceClass
);
497 // initialize __kSCNetworkInterfaceIPv4
498 _CFRuntimeSetInstanceTypeID(&__kSCNetworkInterfaceIPv4
, __kSCNetworkInterfaceTypeID
);
499 __kSCNetworkInterfaceIPv4
.interface_type
= kSCNetworkInterfaceTypeIPv4
;
500 __kSCNetworkInterfaceIPv4
.localized_key
= CFSTR("ipv4");
502 // get CFBundleRef for SystemConfiguration.framework
503 bundle
= _SC_CFBundleGet();
505 // get mach port used to communication with IOKit
506 kr
= IOMasterPort(MACH_PORT_NULL
, &masterPort
);
507 if (kr
!= KERN_SUCCESS
) {
508 SCLog(TRUE
, LOG_DEBUG
,
509 CFSTR("__SCNetworkInterfaceInitialize(), could not get IOMasterPort, kr = 0x%x"),
518 SCNetworkInterfacePrivateRef
519 __SCNetworkInterfaceCreatePrivate(CFAllocatorRef allocator
,
520 SCNetworkInterfaceRef interface
,
521 SCPreferencesRef prefs
,
522 CFStringRef serviceID
,
525 SCNetworkInterfacePrivateRef interfacePrivate
;
528 /* initialize runtime */
529 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
531 /* allocate target */
532 size
= sizeof(SCNetworkInterfacePrivate
) - sizeof(CFRuntimeBase
);
533 interfacePrivate
= (SCNetworkInterfacePrivateRef
)_CFRuntimeCreateInstance(allocator
,
534 __kSCNetworkInterfaceTypeID
,
537 if (interfacePrivate
== NULL
) {
541 interfacePrivate
->interface_type
= NULL
;
542 interfacePrivate
->name
= NULL
;
543 interfacePrivate
->localized_name
= NULL
;
544 interfacePrivate
->localized_key
= NULL
;
545 interfacePrivate
->localized_arg1
= NULL
;
546 interfacePrivate
->localized_arg2
= NULL
;
547 interfacePrivate
->interface
= (interface
!= NULL
) ? CFRetain(interface
) : NULL
;
548 interfacePrivate
->prefs
= (prefs
!= NULL
) ? CFRetain(prefs
) : NULL
;
549 interfacePrivate
->serviceID
= (serviceID
!= NULL
) ? CFRetain(serviceID
) : NULL
;
550 interfacePrivate
->unsaved
= NULL
;
551 interfacePrivate
->entity_device
= NULL
;
552 interfacePrivate
->entity_type
= NULL
;
553 interfacePrivate
->entity_subtype
= NULL
;
554 interfacePrivate
->supported_interface_types
= NULL
;
555 interfacePrivate
->supported_protocol_types
= NULL
;
556 interfacePrivate
->address
= NULL
;
557 interfacePrivate
->addressString
= NULL
;
558 interfacePrivate
->builtin
= FALSE
;
559 interfacePrivate
->path
= (path
!= NULL
) ? CFStringCreateWithCString(NULL
, path
, kCFStringEncodingUTF8
)
561 interfacePrivate
->location
= NULL
;
562 interfacePrivate
->overrides
= NULL
;
563 interfacePrivate
->modemIsV92
= FALSE
;
564 interfacePrivate
->supportsBond
= FALSE
;
565 interfacePrivate
->supportsVLAN
= FALSE
;
566 interfacePrivate
->type
= NULL
;
567 interfacePrivate
->unit
= NULL
;
568 interfacePrivate
->sort_order
= kSortUnknown
;
569 interfacePrivate
->bond
.interfaces
= NULL
;
570 interfacePrivate
->bond
.mode
= NULL
;
571 interfacePrivate
->bond
.options
= NULL
;
572 interfacePrivate
->vlan
.interface
= NULL
;
573 interfacePrivate
->vlan
.tag
= NULL
;
574 interfacePrivate
->vlan
.options
= NULL
;
576 return interfacePrivate
;
582 __SCNetworkInterfaceSupportsVLAN(CFStringRef bsd_if
)
586 struct if_msghdr
* ifm
;
587 char * if_name
= NULL
;
588 unsigned int if_index
;
590 Boolean vlanOK
= FALSE
;
592 // get the interface index
593 if_name
= _SC_cfstring_to_cstring(bsd_if
, NULL
, 0, kCFStringEncodingASCII
);
594 if (if_name
== NULL
) {
595 return FALSE
; // if conversion error
597 if_index
= if_nametoindex(if_name
);
599 goto done
; // if unknown interface
602 // get information for the specified interface
607 mib
[4] = NET_RT_IFLIST
;
608 mib
[5] = if_index
; /* ask for exactly one interface */
610 if (sysctl(mib
, 6, NULL
, &buf_len
, NULL
, 0) == -1) {
611 SCLog(TRUE
, LOG_ERR
, CFSTR("sysctl() size failed: %s"), strerror(errno
));
614 buf
= CFAllocatorAllocate(NULL
, buf_len
, 0);
615 if (sysctl(mib
, 6, buf
, &buf_len
, NULL
, 0) == -1) {
616 SCLog(TRUE
, LOG_ERR
, CFSTR("sysctl() failed: %s"), strerror(errno
));
620 // check the link type and hwassist flags
621 ifm
= (struct if_msghdr
*)buf
;
622 switch (ifm
->ifm_type
) {
624 #if defined(IF_HWASSIST_VLAN_TAGGING) && defined(IF_HWASSIST_VLAN_MTU)
625 struct if_data
*if_data
= &ifm
->ifm_data
;
627 if (if_data
->ifi_hwassist
& (IF_HWASSIST_VLAN_TAGGING
| IF_HWASSIST_VLAN_MTU
)) {
637 if (if_name
!= NULL
) CFAllocatorDeallocate(NULL
, if_name
);
638 if (buf
!= NULL
) CFAllocatorDeallocate(NULL
, buf
);
645 SCNetworkInterfacePrivateRef
646 _SCBondInterfaceCreatePrivate(CFAllocatorRef allocator
,
649 SCNetworkInterfacePrivateRef interfacePrivate
;
651 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
, NULL
);
652 if (interfacePrivate
== NULL
) {
656 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBond
;
657 interfacePrivate
->entity_type
= kSCEntNetEthernet
;
658 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, bond_if
);
659 interfacePrivate
->builtin
= TRUE
;
660 interfacePrivate
->supportsVLAN
= __SCNetworkInterfaceSupportsVLAN(bond_if
);
661 interfacePrivate
->sort_order
= kSortBond
;
663 interfacePrivate
->localized_key
= CFSTR("bond");
664 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
666 interfacePrivate
->bond
.interfaces
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
667 // interfacePrivate->bond.mode = NULL;
668 // interfacePrivate->bond.options = NULL;
670 return interfacePrivate
;
675 SCNetworkInterfacePrivateRef
676 _SCVLANInterfaceCreatePrivate(CFAllocatorRef allocator
,
679 SCNetworkInterfacePrivateRef interfacePrivate
;
681 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
, NULL
);
682 if (interfacePrivate
== NULL
) {
686 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeVLAN
;
687 interfacePrivate
->entity_type
= kSCEntNetEthernet
;
688 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, vlan_if
);
689 interfacePrivate
->builtin
= TRUE
;
690 interfacePrivate
->sort_order
= kSortVLAN
;
692 interfacePrivate
->localized_key
= CFSTR("vlan");
693 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
695 // interfacePrivate->vlan.interface = NULL;
696 // interfacePrivate->vlan.tag = NULL;
697 // interfacePrivate->vlan.options = NULL;
699 return interfacePrivate
;
704 #pragma mark Interface ordering
708 split_path(CFStringRef path
)
710 CFArrayRef components
;
711 CFMutableStringRef nPath
;
713 // turn '@'s into '/'s
714 nPath
= CFStringCreateMutableCopy(NULL
, 0, path
);
715 (void) CFStringFindAndReplace(nPath
,
718 CFRangeMake(0, CFStringGetLength(nPath
)),
721 // split path into components to be compared
722 components
= CFStringCreateArrayBySeparatingStrings(NULL
, nPath
, CFSTR("/"));
730 _SCNetworkInterfaceCompare(const void *val1
, const void *val2
, void *context
)
732 SCNetworkInterfacePrivateRef dev1
= (SCNetworkInterfacePrivateRef
)val1
;
733 SCNetworkInterfacePrivateRef dev2
= (SCNetworkInterfacePrivateRef
)val2
;
734 CFComparisonResult res
= kCFCompareEqualTo
;
736 /* sort by interface type */
737 if (dev1
->sort_order
!= dev2
->sort_order
) {
738 if (dev1
->sort_order
< dev2
->sort_order
) {
739 res
= kCFCompareLessThan
;
741 res
= kCFCompareGreaterThan
;
746 /* built-in interfaces sort first */
747 if (dev1
->builtin
!= dev2
->builtin
) {
749 res
= kCFCompareLessThan
;
751 res
= kCFCompareGreaterThan
;
756 /* ... and then, sort built-in interfaces by "location" */
758 if (dev1
->location
!= dev2
->location
) {
759 if (isA_CFString(dev1
->location
)) {
760 if (isA_CFString(dev2
->location
)) {
761 res
= CFStringCompare(dev1
->location
, dev2
->location
, 0);
763 res
= kCFCompareLessThan
;
766 res
= kCFCompareGreaterThan
;
769 if (res
!= kCFCompareEqualTo
) {
775 /* ... and, then sort by IOPathMatch */
776 if ((dev1
->path
!= NULL
) && (dev2
->path
!= NULL
)) {
777 CFArrayRef elements1
;
778 CFArrayRef elements2
;
784 elements1
= split_path(dev1
->path
);
785 n1
= CFArrayGetCount(elements1
);
787 elements2
= split_path(dev2
->path
);
788 n2
= CFArrayGetCount(elements2
);
790 n
= (n1
<= n2
) ? n1
: n2
;
791 for (i
= 0; i
< n
; i
++) {
800 e1
= CFArrayGetValueAtIndex(elements1
, i
);
801 e2
= CFArrayGetValueAtIndex(elements2
, i
);
803 str
= _SC_cfstring_to_cstring(e1
, NULL
, 0, kCFStringEncodingUTF8
);
805 q1
= strtoq(str
, &end
, 16);
806 isNum
= ((*str
!= '\0') && (*end
== '\0') && (errno
== 0));
807 CFAllocatorDeallocate(NULL
, str
);
810 // if e1 is a valid numeric string
811 str
= _SC_cfstring_to_cstring(e2
, NULL
, 0, kCFStringEncodingUTF8
);
813 q2
= strtoq(str
, &end
, 16);
814 isNum
= ((*str
!= '\0') && (*end
== '\0') && (errno
== 0));
815 CFAllocatorDeallocate(NULL
, str
);
818 // if e2 is also a valid numeric string
821 res
= kCFCompareEqualTo
;
823 } else if (q1
< q2
) {
824 res
= kCFCompareLessThan
;
826 res
= kCFCompareGreaterThan
;
832 res
= CFStringCompare(e1
, e2
, 0);
833 if (res
!= kCFCompareEqualTo
) {
838 if (res
== kCFCompareEqualTo
) {
840 res
= kCFCompareLessThan
;
841 } else if (n1
< n2
) {
842 res
= kCFCompareGreaterThan
;
846 CFRelease(elements1
);
847 CFRelease(elements2
);
849 if (res
!= kCFCompareEqualTo
) {
854 /* ... and lastly, sort by BSD interface name */
855 if ((dev1
->entity_device
!= NULL
) && (dev2
->entity_device
!= NULL
)) {
856 res
= CFStringCompare(dev1
->entity_device
, dev2
->entity_device
, 0);
864 sort_interfaces(CFMutableArrayRef all_interfaces
)
866 int n
= CFArrayGetCount(all_interfaces
);
872 CFArraySortValues(all_interfaces
, CFRangeMake(0, n
), _SCNetworkInterfaceCompare
, NULL
);
879 __SCNetworkInterfaceOrder(SCNetworkInterfaceRef interface
)
881 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
883 return interfacePrivate
->sort_order
;
888 #pragma mark Interface details
892 IOCopyCFStringValue(CFTypeRef ioVal
)
894 if (isA_CFString(ioVal
)) {
895 return CFStringCreateCopy(NULL
, ioVal
);
898 if (isA_CFData(ioVal
)) {
899 return CFStringCreateWithCString(NULL
,
900 (const char *)CFDataGetBytePtr(ioVal
),
901 kCFStringEncodingUTF8
);
909 IODictionaryCopyCFStringValue(CFDictionaryRef io_dict
, CFStringRef io_key
)
913 ioVal
= CFDictionaryGetValue(io_dict
, io_key
);
914 return IOCopyCFStringValue(ioVal
);
919 IOStringValueHasPrefix(CFTypeRef ioVal
, CFStringRef prefix
)
921 Boolean match
= FALSE
;
922 CFIndex prefixLen
= CFStringGetLength(prefix
);
923 CFStringRef str
= ioVal
;
925 if (!isA_CFString(ioVal
)) {
926 if (isA_CFData(ioVal
)) {
927 str
= CFStringCreateWithCStringNoCopy(NULL
,
928 (const char *)CFDataGetBytePtr(ioVal
),
929 kCFStringEncodingUTF8
,
937 (CFStringGetLength(str
) >= prefixLen
) &&
938 (CFStringCompareWithOptions(str
,
940 CFRangeMake(0, prefixLen
),
941 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
)) {
945 if (str
!= ioVal
) CFRelease(str
);
950 static const struct {
951 const CFStringRef name
;
952 const CFStringRef slot
;
953 } slot_mappings
[] = {
955 { CFSTR("A1") , CFSTR("1") },
956 { CFSTR("B1") , CFSTR("2") },
957 { CFSTR("C1") , CFSTR("3") },
959 // Blue&White G3, Yikes G4
960 { CFSTR("J12"), CFSTR("1") },
961 { CFSTR("J11"), CFSTR("2") },
962 { CFSTR("J10"), CFSTR("3") },
963 { CFSTR("J9"), CFSTR("4") },
966 { CFSTR("A") , CFSTR("1") },
967 { CFSTR("B") , CFSTR("2") },
968 { CFSTR("C") , CFSTR("3") },
969 { CFSTR("D") , CFSTR("4") },
971 // Digital Audio G4 (and later models)
972 { CFSTR("1") , CFSTR("1") },
973 { CFSTR("2") , CFSTR("2") },
974 { CFSTR("3") , CFSTR("3") },
975 { CFSTR("4") , CFSTR("4") },
976 { CFSTR("5") , CFSTR("5") }
981 pci_slot(io_registry_entry_t interface
, CFTypeRef
*pci_slot_name
)
984 io_registry_entry_t parent
;
985 CFMutableStringRef slot
;
989 if (pci_slot_name
!= NULL
) *pci_slot_name
= NULL
;
991 slot_name
= IORegistryEntryCreateCFProperty(interface
, CFSTR("AAPL,slot-name"), NULL
, 0);
992 if (slot_name
!= NULL
) {
995 slot
= CFStringCreateMutable(NULL
, 0);
996 if (isA_CFString(slot_name
)) {
997 if (pci_slot_name
!= NULL
) *pci_slot_name
= CFStringCreateCopy(NULL
, slot_name
);
998 CFStringAppend(slot
, slot_name
);
999 } else if (isA_CFData(slot_name
)) {
1000 if (pci_slot_name
!= NULL
) *pci_slot_name
= CFDataCreateCopy(NULL
, slot_name
);
1001 CFStringAppendCString(slot
,
1002 (const char *)CFDataGetBytePtr(slot_name
),
1003 kCFStringEncodingUTF8
);
1006 if (CFStringGetLength(slot
) > 5) {
1007 (void) CFStringFindAndReplace(slot
,
1011 kCFCompareCaseInsensitive
|kCFCompareAnchored
);
1014 for (i
= 0; i
< sizeof(slot_mappings
)/sizeof(slot_mappings
[0]); i
++) {
1015 if (CFStringCompare(slot
,
1016 slot_mappings
[i
].name
,
1017 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
1019 slot
= (CFMutableStringRef
)CFRetain(slot_mappings
[i
].slot
);
1024 CFRelease(slot_name
);
1027 kr
= IORegistryEntryGetParentEntry(interface
, kIOServicePlane
, &parent
);
1029 case kIOReturnSuccess
: {
1030 CFTypeRef parent_pci_slot_name
= NULL
;
1031 CFStringRef parent_slot
;
1033 parent_slot
= pci_slot(parent
, &parent_pci_slot_name
);
1034 if (parent_slot
!= NULL
) {
1035 if (slot
!= NULL
) CFRelease(slot
);
1036 slot
= (CFMutableStringRef
)parent_slot
;
1038 if (pci_slot_name
!= NULL
) {
1039 if (*pci_slot_name
!= NULL
) CFRelease(*pci_slot_name
);
1040 *pci_slot_name
= parent_pci_slot_name
;
1042 CFRelease(parent_pci_slot_name
);
1046 IOObjectRelease(parent
);
1049 case kIOReturnNoDevice
:
1050 // if we have hit the root node
1053 SCLog(TRUE
, LOG_DEBUG
, CFSTR("pci_slot IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr
);
1061 static CFComparisonResult
1062 compare_bsdNames(const void *val1
, const void *val2
, void *context
)
1064 CFStringRef bsd1
= (CFStringRef
)val1
;
1065 CFStringRef bsd2
= (CFStringRef
)val2
;
1067 return CFStringCompare(bsd1
, bsd2
, 0);
1072 pci_port(CFTypeRef slot_name
, CFStringRef bsdName
)
1075 CFStringRef port_name
= NULL
;
1076 CFMutableArrayRef port_names
;
1079 CFStringRef match_keys
[2];
1080 CFTypeRef match_vals
[2];
1081 CFDictionaryRef match_dict
;
1082 CFDictionaryRef matching
;
1083 io_registry_entry_t slot
;
1084 io_iterator_t slot_iterator
= MACH_PORT_NULL
;
1086 match_keys
[0] = CFSTR("AAPL,slot-name");
1087 match_vals
[0] = slot_name
;
1089 match_dict
= CFDictionaryCreate(NULL
,
1090 (const void **)match_keys
,
1091 (const void **)match_vals
,
1093 &kCFTypeDictionaryKeyCallBacks
,
1094 &kCFTypeDictionaryValueCallBacks
);
1096 match_keys
[0] = CFSTR(kIOProviderClassKey
);
1097 match_vals
[0] = CFSTR("IOPCIDevice");
1099 match_keys
[1] = CFSTR(kIOPropertyMatchKey
);
1100 match_vals
[1] = match_dict
;
1102 // note: the "matching" dictionary will be consumed by the following
1103 matching
= CFDictionaryCreate(NULL
,
1104 (const void **)match_keys
,
1105 (const void **)match_vals
,
1106 sizeof(match_keys
)/sizeof(match_keys
[0]),
1107 &kCFTypeDictionaryKeyCallBacks
,
1108 &kCFTypeDictionaryValueCallBacks
);
1109 CFRelease(match_dict
);
1111 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &slot_iterator
);
1112 if (kr
!= kIOReturnSuccess
) {
1113 SCLog(TRUE
, LOG_DEBUG
, CFSTR("pci_port IOServiceGetMatchingServices() failed, kr = 0x%x"), kr
);
1114 return MACH_PORT_NULL
;
1117 port_names
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1119 while ((slot
= IOIteratorNext(slot_iterator
)) != MACH_PORT_NULL
) {
1120 io_registry_entry_t child
;
1121 io_iterator_t child_iterator
= MACH_PORT_NULL
;
1123 kr
= IORegistryEntryCreateIterator(slot
,
1125 kIORegistryIterateRecursively
,
1127 if (kr
!= kIOReturnSuccess
) {
1128 SCLog(TRUE
, LOG_DEBUG
, CFSTR("pci_port IORegistryEntryCreateIterator() failed, kr = 0x%x"), kr
);
1129 return MACH_PORT_NULL
;
1132 while ((child
= IOIteratorNext(child_iterator
)) != MACH_PORT_NULL
) {
1133 if (IOObjectConformsTo(child
, kIONetworkInterfaceClass
)) {
1134 CFStringRef if_bsdName
;
1136 if_bsdName
= IORegistryEntryCreateCFProperty(child
,
1137 CFSTR(kIOBSDNameKey
),
1140 if (if_bsdName
!= NULL
) {
1141 CFArrayAppendValue(port_names
, if_bsdName
);
1142 CFRelease(if_bsdName
);
1145 IOObjectRelease(child
);
1147 IOObjectRelease(child_iterator
);
1148 IOObjectRelease(slot
);
1150 IOObjectRelease(slot_iterator
);
1152 n
= CFArrayGetCount(port_names
);
1154 CFArraySortValues(port_names
, CFRangeMake(0, n
), compare_bsdNames
, NULL
);
1155 n
= CFArrayGetFirstIndexOfValue(port_names
, CFRangeMake(0, n
), bsdName
);
1156 if (n
!= kCFNotFound
) {
1157 port_name
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%d"), n
+ 1);
1161 CFRelease(port_names
);
1167 pci_slot_info(io_registry_entry_t interface
, CFStringRef
*slot_name
, CFStringRef
*port_name
)
1169 CFStringRef bsd_name
;
1171 CFTypeRef pci_slot_name
;
1176 bsd_name
= IORegistryEntryCreateCFProperty(interface
, CFSTR(kIOBSDNameKey
), NULL
, 0);
1177 if (bsd_name
== NULL
) {
1181 *slot_name
= pci_slot(interface
, &pci_slot_name
);
1182 if (*slot_name
!= NULL
) {
1183 if (pci_slot_name
!= NULL
) {
1184 *port_name
= pci_port(pci_slot_name
, bsd_name
);
1185 CFRelease(pci_slot_name
);
1190 CFRelease(bsd_name
);
1196 isBuiltin(io_registry_entry_t interface
)
1200 slot
= pci_slot(interface
, NULL
);
1202 // interfaces which have a "slot" are not built-in
1212 #pragma mark Interface enumeration
1215 typedef Boolean (*processInterface
)(SCNetworkInterfacePrivateRef interfacePrivate
,
1216 io_registry_entry_t interface
,
1217 CFDictionaryRef interface_dict
,
1218 io_registry_entry_t controller
,
1219 CFDictionaryRef controller_dict
,
1220 io_registry_entry_t bus
,
1221 CFDictionaryRef bus_dict
);
1225 processNetworkInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1226 io_registry_entry_t interface
,
1227 CFDictionaryRef interface_dict
,
1228 io_registry_entry_t controller
,
1229 CFDictionaryRef controller_dict
,
1230 io_registry_entry_t bus
,
1231 CFDictionaryRef bus_dict
)
1241 num
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceType
));
1242 if (isA_CFNumber(num
) &&
1243 CFNumberGetValue(num
, kCFNumberIntType
, &ift
)) {
1244 interfacePrivate
->type
= CFRetain(num
);
1246 SCLog(TRUE
, LOG_DEBUG
, CFSTR("processNetworkInterface() failed, no interface type"));
1254 if ((IOObjectConformsTo(controller
, "IO80211Controller")) ||
1255 (IOObjectConformsTo(controller
, "AirPortPCI" )) ||
1256 (IOObjectConformsTo(controller
, "AirPortDriver" ))) {
1257 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
1258 interfacePrivate
->entity_type
= kSCEntNetEthernet
;
1259 interfacePrivate
->sort_order
= kSortAirPort
;
1260 } else if (IOObjectConformsTo(controller
, "IOBluetoothBNEPDriver")) {
1261 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1262 interfacePrivate
->entity_type
= kSCEntNetEthernet
;
1263 interfacePrivate
->sort_order
= kSortBluetoothPAN
;
1265 str
= IODictionaryCopyCFStringValue(bus_dict
, CFSTR("name"));
1266 if ((str
!= NULL
) && CFEqual(str
, CFSTR("radio"))) {
1267 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
; // ??
1268 interfacePrivate
->entity_type
= kSCEntNetEthernet
;
1269 interfacePrivate
->sort_order
= kSortOtherWireless
;
1271 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1272 interfacePrivate
->entity_type
= kSCEntNetEthernet
;
1273 interfacePrivate
->sort_order
= kSortEthernet
;
1275 // BOND support only enabled for ethernet devices
1276 interfacePrivate
->supportsBond
= TRUE
;
1279 if (str
!= NULL
) CFRelease(str
);
1283 bVal
= isA_CFBoolean(CFDictionaryGetValue(interface_dict
, CFSTR(kIOBuiltin
)));
1285 bVal
= isA_CFBoolean(CFDictionaryGetValue(interface_dict
, CFSTR(kIOPrimaryInterface
)));
1288 interfacePrivate
->builtin
= CFBooleanGetValue(bVal
);
1290 interfacePrivate
->builtin
= isBuiltin(interface
);
1294 interfacePrivate
->location
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOLocation
));
1297 num
= CFDictionaryGetValue(controller_dict
, CFSTR(kIOFeatures
));
1298 if (isA_CFNumber(num
) &&
1299 CFNumberGetValue(num
, kCFNumberIntType
, & iVal
)) {
1300 if (iVal
& (kIONetworkFeatureHardwareVlan
| kIONetworkFeatureSoftwareVlan
)) {
1301 interfacePrivate
->supportsVLAN
= TRUE
;
1306 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
)) {
1307 interfacePrivate
->localized_key
= CFSTR("airport");
1308 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN
) {
1309 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan");
1310 } else if (interfacePrivate
->sort_order
== kSortOtherWireless
) {
1311 interfacePrivate
->localized_key
= CFSTR("wireless");
1312 interfacePrivate
->localized_arg1
= CFRetain(CFSTR("")); // ??
1313 } else if (interfacePrivate
->builtin
) {
1314 if ((interfacePrivate
->location
== NULL
) ||
1315 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1316 interfacePrivate
->localized_key
= CFSTR("ether");
1318 interfacePrivate
->localized_key
= CFSTR("multiether");
1319 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->location
);
1322 CFStringRef provider
;
1324 // check provider class
1325 provider
= IORegistryEntrySearchCFProperty(interface
,
1327 CFSTR(kIOProviderClassKey
),
1329 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1330 if (provider
!= NULL
) {
1331 if (CFEqual(provider
, CFSTR("IOPCIDevice"))) {
1332 CFStringRef port_name
;
1333 CFStringRef slot_name
;
1335 if (pci_slot_info(interface
, &slot_name
, &port_name
)) {
1336 if (port_name
== NULL
) {
1337 interfacePrivate
->localized_key
= CFSTR("pci-ether");
1338 interfacePrivate
->localized_arg1
= slot_name
;
1340 interfacePrivate
->localized_key
= CFSTR("pci-multiether");
1341 interfacePrivate
->localized_arg1
= slot_name
;
1342 interfacePrivate
->localized_arg2
= port_name
;
1346 CFRelease(provider
);
1349 if (interfacePrivate
->localized_key
== NULL
) {
1350 // if no provider, not a PCI device, or no slot information
1351 interfacePrivate
->localized_key
= CFSTR("generic-ether");
1352 interfacePrivate
->localized_arg1
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOBSDNameKey
));
1359 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeFireWire
;
1362 interfacePrivate
->entity_type
= kSCEntNetFireWire
;
1365 interfacePrivate
->builtin
= isBuiltin(interface
);
1368 interfacePrivate
->sort_order
= kSortFireWire
;
1371 if (interfacePrivate
->builtin
) {
1372 interfacePrivate
->localized_key
= CFSTR("firewire");
1374 CFStringRef slot_name
;
1376 slot_name
= pci_slot(interface
, NULL
);
1377 if (slot_name
!= NULL
) {
1378 interfacePrivate
->localized_key
= CFSTR("pci-firewire");
1379 interfacePrivate
->localized_arg1
= slot_name
;
1385 SCLog(TRUE
, LOG_DEBUG
, CFSTR("processNetworkInterface() failed, unknown interface type = %d"), ift
);
1390 interfacePrivate
->entity_device
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOBSDNameKey
));
1392 // Hardware (MAC) address
1393 data
= CFDictionaryGetValue(controller_dict
, CFSTR(kIOMACAddress
));
1394 if (isA_CFData(data
)) {
1395 interfacePrivate
->address
= CFRetain(data
);
1399 num
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceUnit
));
1400 if (isA_CFNumber(num
) &&
1401 CFNumberGetValue(num
, kCFNumberIntType
, & iVal
)) {
1402 interfacePrivate
->unit
= CFRetain(num
);
1410 set_connection_script(SCNetworkInterfacePrivateRef interfacePrivate
, CFStringRef script
)
1412 CFDictionaryRef dict
;
1413 CFMutableDictionaryRef newDict
;
1415 if (interfacePrivate
->overrides
== NULL
) {
1416 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
1418 &kCFTypeDictionaryKeyCallBacks
,
1419 &kCFTypeDictionaryValueCallBacks
);
1422 dict
= CFDictionaryGetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
1424 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
1426 newDict
= CFDictionaryCreateMutable(NULL
,
1428 &kCFTypeDictionaryKeyCallBacks
,
1429 &kCFTypeDictionaryValueCallBacks
);
1431 if (script
!= NULL
) {
1432 CFDictionarySetValue(newDict
, kSCPropNetModemConnectionScript
, script
);
1434 CFDictionaryRemoveValue(newDict
, kSCPropNetModemConnectionScript
);
1436 if (CFDictionaryGetCount(newDict
) > 0) {
1437 CFDictionarySetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
, newDict
);
1439 CFDictionaryRemoveValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
1443 if (CFDictionaryGetCount(interfacePrivate
->overrides
) == 0) {
1444 CFRelease(interfacePrivate
->overrides
);
1445 interfacePrivate
->overrides
= NULL
;
1452 is_valid_connection_script(CFStringRef script
)
1454 char ccl
[MAXPATHLEN
];
1455 char path
[MAXPATHLEN
];
1456 NSSearchPathEnumerationState state
;
1458 (void) _SC_cfstring_to_cstring(script
,
1461 kCFStringEncodingUTF8
);
1463 state
= NSStartSearchPathEnumeration(NSLibraryDirectory
,
1464 NSLocalDomainMask
|NSSystemDomainMask
);
1465 while ((state
= NSGetNextSearchPathEnumeration(state
, path
))) {
1467 struct stat statBuf
;
1469 if (ccl
[0] == '/') {
1470 path
[0] = '\0'; // if modemCCL is a full path
1472 strlcat(path
, "/Modem Scripts/", sizeof(path
));
1474 strlcat(path
, ccl
, sizeof(path
));
1476 if (stat(path
, &statBuf
) != 0) {
1477 if (errno
== ENOENT
) {
1481 SCLog(TRUE
, LOG_DEBUG
,
1482 CFSTR("processSerialInterface stat() failed: %s"),
1486 if (S_ISREG(statBuf
.st_mode
)) {
1487 // if we have a valid CCL script
1491 #define BUNDLE_EXT ".ccl"
1492 #define BUNDLE_EXT_LEN sizeof(BUNDLE_EXT) - 1
1497 if ((n
<= BUNDLE_EXT_LEN
) ||
1498 (strstr(&path
[n
- BUNDLE_EXT_LEN
], BUNDLE_EXT
) == NULL
)) {
1499 strlcat(path
, BUNDLE_EXT
, sizeof(path
));
1500 if (stat(path
, &statBuf
) != 0) {
1501 if (errno
== ENOENT
) {
1505 SCLog(TRUE
, LOG_DEBUG
,
1506 CFSTR("processSerialInterface stat() failed: %s"),
1511 if (S_ISDIR(statBuf
.st_mode
)) {
1512 // if we have a valid CCL bundle
1522 processSerialInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1523 io_registry_entry_t interface
,
1524 CFDictionaryRef interface_dict
,
1525 io_registry_entry_t controller
,
1526 CFDictionaryRef controller_dict
,
1527 io_registry_entry_t bus
,
1528 CFDictionaryRef bus_dict
)
1531 Boolean isModem
= FALSE
;
1532 CFStringRef modemCCL
= NULL
;
1537 val
= IORegistryEntrySearchCFProperty(interface
,
1539 CFSTR("HiddenPort"),
1541 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1544 return FALSE
; // if this interface should not be exposed
1548 str
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOTTYBaseNameKey
));
1556 * Exclude ports named "irda" because otherwise the IrDA ports on the
1557 * original iMac (rev's A through D) show up as serial ports. Given
1558 * that only the rev A actually had an IrDA port, and Mac OS X doesn't
1559 * even support it, these ports definitely shouldn't be listed.
1561 if (CFStringCompare(str
,
1563 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
1567 if (IOStringValueHasPrefix(str
, CFSTR("bluetooth"))) {
1569 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBluetooth
;
1570 interfacePrivate
->sort_order
= kSortBluetooth
;
1571 } else if (IOStringValueHasPrefix(str
, CFSTR("irda-ircomm"))) {
1573 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIrDA
;
1574 interfacePrivate
->sort_order
= kSortIrDA
;
1575 } else if (IOStringValueHasPrefix(str
, CFSTR("wwan"))) {
1577 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeWWAN
;
1578 interfacePrivate
->sort_order
= kSortWWAN
;
1581 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeModem
;
1582 interfacePrivate
->sort_order
= kSortModem
;
1585 val
= IORegistryEntrySearchCFProperty(interface
,
1587 CFSTR(kIODeviceSupportsHoldKey
),
1589 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1593 if (isA_CFNumber(val
) &&
1594 CFNumberGetValue(val
, kCFNumberSInt32Type
, &v92
)) {
1595 interfacePrivate
->modemIsV92
= (v92
== 1);
1602 interfacePrivate
->entity_type
= kSCEntNetModem
;
1604 // Entity (Hardware)
1605 ift
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOSerialBSDTypeKey
));
1606 if (!isA_CFString(ift
)) {
1610 if (CFEqual(ift
, CFSTR(kIOSerialBSDModemType
))) {
1614 if (CFEqual(str
, CFSTR("modem"))) {
1615 interfacePrivate
->builtin
= TRUE
;
1616 interfacePrivate
->sort_order
= kSortInternalModem
;
1617 } else if (CFEqual(str
, CFSTR("usbmodem"))) {
1618 interfacePrivate
->sort_order
= kSortUSBModem
;
1620 } else if (CFEqual(ift
, CFSTR(kIOSerialBSDRS232Type
))) {
1622 interfacePrivate
->sort_order
= kSortSerialPort
;
1628 interfacePrivate
->entity_device
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOTTYDeviceKey
));
1630 // configuration template overrides
1631 val
= IORegistryEntrySearchCFProperty(interface
,
1633 CFSTR("DevicePPPOverrides"),
1635 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1637 if (isA_CFDictionary(val
)) {
1638 if (interfacePrivate
->overrides
== NULL
) {
1639 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
1641 &kCFTypeDictionaryKeyCallBacks
,
1642 &kCFTypeDictionaryValueCallBacks
);
1644 CFDictionarySetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypePPP
, val
);
1649 val
= IORegistryEntrySearchCFProperty(interface
,
1651 CFSTR("DeviceModemOverrides"),
1653 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1655 if (isA_CFDictionary(val
)) {
1656 if (interfacePrivate
->overrides
== NULL
) {
1657 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
1659 &kCFTypeDictionaryKeyCallBacks
,
1660 &kCFTypeDictionaryValueCallBacks
);
1662 CFDictionarySetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
, val
);
1664 modemCCL
= CFDictionaryGetValue(val
, kSCPropNetModemConnectionScript
);
1665 modemCCL
= isA_CFString(modemCCL
);
1671 if (modemCCL
== NULL
) {
1672 val
= IORegistryEntrySearchCFProperty(interface
,
1676 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1678 modemCCL
= IOCopyCFStringValue(val
);
1679 if (modemCCL
!= NULL
) {
1680 set_connection_script(interfacePrivate
, modemCCL
);
1681 CFRelease(modemCCL
);
1689 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIrDA
)) {
1690 interfacePrivate
->localized_key
= CFSTR("irda");
1691 } else if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBluetooth
)) {
1692 interfacePrivate
->localized_key
= CFSTR("bluetooth");
1694 CFStringRef localized
= NULL
;
1695 CFStringRef name
= NULL
;
1696 CFMutableStringRef port
;
1698 port
= CFStringCreateMutableCopy(NULL
, 0, str
);
1699 CFStringLowercase(port
, NULL
);
1702 CFStringAppend(port
, CFSTR("-port"));
1705 // set non-localized name
1706 if (bundle
!= NULL
) {
1707 name
= copy_interface_string(bundle
, port
, FALSE
);
1710 if (!CFEqual(port
, name
)) {
1711 // if [English] localization available
1712 interfacePrivate
->name
= name
;
1714 // if no [English] localization available, use TTY base name
1716 interfacePrivate
->name
= CFStringCreateCopy(NULL
, str
);
1719 interfacePrivate
->name
= CFStringCreateCopy(NULL
, str
);
1722 // set localized name
1723 if (bundle
!= NULL
) {
1724 localized
= copy_interface_string(bundle
, port
, TRUE
);
1726 if (localized
!= NULL
) {
1727 if (!CFEqual(port
, localized
)) {
1728 // if localization available
1729 interfacePrivate
->localized_name
= localized
;
1731 // if no localization available, use TTY base name
1732 CFRelease(localized
);
1733 interfacePrivate
->localized_name
= CFStringCreateCopy(NULL
, str
);
1736 interfacePrivate
->localized_name
= CFStringCreateCopy(NULL
, str
);
1739 if (!isModem
|| !CFEqual(str
, CFSTR("modem"))) {
1740 CFStringRef productName
;
1742 // check if a "Product Name" has been provided
1743 val
= IORegistryEntrySearchCFProperty(interface
,
1745 CFSTR(kIOPropertyProductNameKey
),
1747 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1749 productName
= IOCopyCFStringValue(val
);
1752 if (productName
!= NULL
) {
1753 if (CFStringGetLength(productName
) > 0) {
1754 // if we have a [somewhat reasonable?] product name
1755 if (interfacePrivate
->name
!= NULL
) {
1756 CFRelease(interfacePrivate
->name
);
1758 interfacePrivate
->name
= CFRetain(productName
);
1759 if (interfacePrivate
->localized_name
!= NULL
) {
1760 CFRelease(interfacePrivate
->localized_name
);
1762 interfacePrivate
->localized_name
= CFRetain(productName
);
1764 // if not provided, also check if the product name
1765 // matches a CCL script
1766 if ((modemCCL
== NULL
) &&
1767 is_valid_connection_script(productName
)) {
1768 set_connection_script(interfacePrivate
, productName
);
1769 modemCCL
= productName
;
1773 CFRelease(productName
);
1785 static SCNetworkInterfaceRef
1786 createInterface(io_registry_entry_t interface
, processInterface func
)
1788 io_registry_entry_t bus
= MACH_PORT_NULL
;
1789 CFMutableDictionaryRef bus_dict
= NULL
;
1790 io_registry_entry_t controller
= MACH_PORT_NULL
;
1791 CFMutableDictionaryRef controller_dict
= NULL
;
1792 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
1793 CFMutableDictionaryRef interface_dict
= NULL
;
1797 kr
= IORegistryEntryGetPath(interface
, kIOServicePlane
, path
);
1798 if (kr
!= kIOReturnSuccess
) {
1799 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryGetPath() failed, kr = 0x%x"), kr
);
1803 kr
= IORegistryEntryCreateCFProperties(interface
, &interface_dict
, NULL
, kNilOptions
);
1804 if (kr
!= kIOReturnSuccess
) {
1805 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryCreateCFProperties() failed, kr = 0x%x"), kr
);
1809 /* get the controller node */
1810 kr
= IORegistryEntryGetParentEntry(interface
, kIOServicePlane
, &controller
);
1811 if (kr
!= KERN_SUCCESS
) {
1812 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr
);
1816 /* get the dictionary associated with the node */
1817 kr
= IORegistryEntryCreateCFProperties(controller
, &controller_dict
, NULL
, kNilOptions
);
1818 if (kr
!= KERN_SUCCESS
) {
1819 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryCreateCFProperties() failed, kr = 0x%x"), kr
);
1823 /* get the bus node */
1824 kr
= IORegistryEntryGetParentEntry(controller
, kIOServicePlane
, &bus
);
1825 if (kr
!= KERN_SUCCESS
) {
1826 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr
);
1830 /* get the dictionary associated with the node */
1831 kr
= IORegistryEntryCreateCFProperties(bus
, &bus_dict
, NULL
, kNilOptions
);
1832 if (kr
!= KERN_SUCCESS
) {
1833 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryCreateCFProperties() failed, kr = 0x%x"), kr
);
1837 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
, path
);
1839 if (!(*func
)(interfacePrivate
, interface
, interface_dict
, controller
, controller_dict
, bus
, bus_dict
)) {
1840 CFRelease(interfacePrivate
);
1841 interfacePrivate
= NULL
;
1846 if (interface_dict
!= NULL
) CFRelease(interface_dict
);
1848 if (controller
!= MACH_PORT_NULL
) IOObjectRelease(controller
);
1849 if (controller_dict
!= NULL
) CFRelease(controller_dict
);
1851 if (bus
!= MACH_PORT_NULL
) IOObjectRelease(bus
);
1852 if (bus_dict
!= NULL
) CFRelease(bus_dict
);
1854 return (SCNetworkInterfaceRef
)interfacePrivate
;
1859 findMatchingInterfaces(CFDictionaryRef matching
, processInterface func
)
1861 CFMutableArrayRef interfaces
;
1862 io_registry_entry_t interface
;
1864 io_iterator_t iterator
= MACH_PORT_NULL
;
1866 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &iterator
);
1867 if (kr
!= kIOReturnSuccess
) {
1868 SCLog(TRUE
, LOG_DEBUG
, CFSTR("findMatchingInterfaces IOServiceGetMatchingServices() failed, kr = 0x%x"), kr
);
1872 interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1874 while ((interface
= IOIteratorNext(iterator
)) != MACH_PORT_NULL
) {
1875 SCNetworkInterfaceRef match
;
1877 match
= createInterface(interface
, func
);
1878 if (match
!= NULL
) {
1879 CFArrayAppendValue(interfaces
, match
);
1883 IOObjectRelease(interface
);
1886 IOObjectRelease(iterator
);
1893 #pragma mark helper functions
1897 findConfiguration(CFStringRef interface_type
)
1901 for (i
= 0; i
< sizeof(configurations
)/sizeof(configurations
[0]); i
++) {
1902 if (CFEqual(interface_type
, *configurations
[i
].interface_type
)) {
1913 __SCNetworkInterfaceGetDefaultConfigurationType(SCNetworkInterfaceRef interface
)
1915 CFIndex interfaceIndex
;
1916 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
1918 if (interfacePrivate
->serviceID
== NULL
) {
1919 // if not associated with a service (yet)
1920 _SCErrorSet(kSCStatusInvalidArgument
);
1924 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
1925 if (interfaceIndex
== kCFNotFound
) {
1926 // unknown interface type, use per-service configuration preferences
1927 return interfacePrivate
->interface_type
; // entity
1930 if (configurations
[interfaceIndex
].entity_hardware
!= NULL
) {
1931 // if configuration information can be associated with this interface type
1932 return *configurations
[interfaceIndex
].entity_hardware
;
1935 _SCErrorSet(kSCStatusInvalidArgument
);
1942 __SCNetworkInterfaceIsValidExtendedConfigurationType(SCNetworkInterfaceRef interface
,
1943 CFStringRef extendedType
,
1944 Boolean requirePerInterface
)
1946 CFStringRef defaultType
;
1947 CFIndex extendedIndex
;
1948 CFIndex interfaceIndex
;
1949 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
1952 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
1953 if (defaultType
== NULL
) {
1957 if (CFEqual(extendedType
, defaultType
)) {
1958 // extended and default configuration types cannot conflict
1962 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
1963 if (interfaceIndex
== kCFNotFound
) {
1964 // configuration information for unknown interface type's
1965 // are stored along with the service and we don't allow
1966 // per-service extended configurations
1970 // It turns out that, for PPP interfaces, we want to be able to store
1971 // some extended interface configuration (e.g. IPSec [for L2TP]). For
1972 // now, I'm commenting out the following test.
1974 // if (requirePerInterface && !configurations[interfaceIndex].per_interface_config) {
1975 // // we don't allow per-service extended configurations
1979 extendedIndex
= findConfiguration(extendedType
);
1980 if (extendedIndex
!= kCFNotFound
) {
1981 // extended type cannot match a known interface type
1987 * Do we match specific/known extended configuration types (e.g. EAPOL)
1988 * and ensure that any non-standard extended configuration types be of
1989 * the form com.myCompany.myType?
1998 _SCErrorSet(kSCStatusInvalidArgument
);
2005 CFStringRef defaultType
;
2006 CFMutableArrayRef types
;
2007 } extendedConfiguration
, *extendedConfigurationRef
;
2011 __addExtendedConfigurationType(const void *key
, const void *value
, void *context
)
2013 CFStringRef extendedType
= (CFStringRef
)key
;
2014 extendedConfigurationRef myContextRef
= (extendedConfigurationRef
)context
;
2016 if (CFEqual(extendedType
, myContextRef
->defaultType
)) {
2017 // do not include the default configuration type
2021 if (CFArrayContainsValue(myContextRef
->types
,
2022 CFRangeMake(0, CFArrayGetCount(myContextRef
->types
)),
2024 // if extendedType already has already been added
2028 CFArrayAppendValue(myContextRef
->types
, extendedType
);
2035 extendedConfigurationTypes(SCNetworkInterfaceRef interface
)
2038 CFIndex interfaceIndex
;
2039 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2040 extendedConfiguration myContext
;
2041 SCNetworkServiceRef service
;
2045 myContext
.defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
2046 if (myContext
.defaultType
== NULL
) {
2047 myContext
.types
= NULL
;
2051 myContext
.types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2053 if (interfacePrivate
->serviceID
== NULL
) {
2054 // if not associated with a service (yet)
2058 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2059 if (interfaceIndex
== kCFNotFound
) {
2060 // we don't allow per-service extended configurations
2064 if (!configurations
[interfaceIndex
].per_interface_config
) {
2065 // known interface type but we still don't allow
2066 // per-service extended configurations
2070 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
2071 interfacePrivate
->prefs
,
2072 interfacePrivate
->serviceID
,
2075 sets
= SCNetworkSetCopyAll(interfacePrivate
->prefs
);
2076 n
= (sets
!= NULL
) ? CFArrayGetCount(sets
) : 0;
2078 for (i
= 0; i
< n
; i
++) {
2079 CFDictionaryRef configs
;
2082 CFArrayRef services
;
2083 SCNetworkSetRef set
;
2085 set
= CFArrayGetValueAtIndex(sets
, i
);
2086 services
= SCNetworkSetCopyServices(set
);
2087 found
= CFArrayContainsValue(services
,
2088 CFRangeMake(0, CFArrayGetCount(services
)),
2090 CFRelease(services
);
2096 // add stored extended configuration types
2097 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
2098 SCNetworkSetGetSetID(set
), // set
2099 interfacePrivate
->entity_device
, // service
2101 configs
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
2103 if (isA_CFDictionary(configs
)) {
2104 CFDictionaryApplyFunction(configs
,
2105 __addExtendedConfigurationType
,
2109 // add not-yet-stored extended configuration types
2110 if (interfacePrivate
->unsaved
!= NULL
) {
2111 CFDictionaryApplyFunction(interfacePrivate
->unsaved
,
2112 __addExtendedConfigurationType
,
2120 if (sets
!= NULL
) CFRelease(sets
);
2124 return myContext
.types
;
2129 copyConfigurationPaths(SCNetworkInterfacePrivateRef interfacePrivate
,
2130 CFStringRef extendedType
)
2132 CFMutableArrayRef array
;
2134 CFIndex interfaceIndex
;
2137 SCNetworkServiceRef service
;
2140 array
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2142 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2143 if (interfaceIndex
== kCFNotFound
) {
2144 // unknown interface type, use per-service configuration preferences
2145 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
2146 interfacePrivate
->serviceID
, // service
2147 extendedType
); // entity
2148 CFArrayAppendValue(array
, path
);
2153 if (!configurations
[interfaceIndex
].per_interface_config
) {
2154 // known interface type, per-service configuration preferences
2155 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
2156 interfacePrivate
->serviceID
, // service
2157 extendedType
); // entity
2158 CFArrayAppendValue(array
, path
);
2163 // known interface type, per-interface configuration preferences
2165 // 1. look for all sets which contain the associated service
2166 // 2. add a per-set path for the interface configuration for
2169 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
2170 interfacePrivate
->prefs
,
2171 interfacePrivate
->serviceID
,
2172 (SCNetworkInterfaceRef
)interfacePrivate
);
2174 sets
= SCNetworkSetCopyAll(interfacePrivate
->prefs
);
2175 n
= (sets
!= NULL
) ? CFArrayGetCount(sets
) : 0;
2177 for (i
= 0; i
< n
; i
++) {
2178 CFArrayRef services
;
2179 SCNetworkSetRef set
;
2181 set
= CFArrayGetValueAtIndex(sets
, i
);
2182 services
= SCNetworkSetCopyServices(set
);
2183 if (CFArrayContainsValue(services
,
2184 CFRangeMake(0, CFArrayGetCount(services
)),
2186 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
2187 SCNetworkSetGetSetID(set
), // set
2188 interfacePrivate
->entity_device
, // service
2189 extendedType
); // entity
2190 CFArrayAppendValue(array
, path
);
2193 CFRelease(services
);
2196 if (CFArrayGetCount(array
) == 0) {
2202 if (sets
!= NULL
) CFRelease(sets
);
2208 #pragma mark SCNetworkInterface <--> preferences entity
2213 __SCNetworkInterfaceCopyInterfaceEntity(SCNetworkInterfaceRef interface
)
2215 CFMutableDictionaryRef entity
;
2216 CFIndex interfaceIndex
;
2217 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2219 entity
= CFDictionaryCreateMutable(NULL
,
2221 &kCFTypeDictionaryKeyCallBacks
,
2222 &kCFTypeDictionaryValueCallBacks
);
2223 if (interfacePrivate
->entity_type
!= NULL
) {
2224 CFDictionarySetValue(entity
,
2225 kSCPropNetInterfaceType
,
2226 interfacePrivate
->entity_type
);
2228 if (interfacePrivate
->entity_subtype
!= NULL
) {
2229 CFDictionarySetValue(entity
,
2230 kSCPropNetInterfaceSubType
,
2231 interfacePrivate
->entity_subtype
);
2233 if (interfacePrivate
->entity_device
!= NULL
) {
2234 CFDictionarySetValue(entity
,
2235 kSCPropNetInterfaceDeviceName
,
2236 interfacePrivate
->entity_device
);
2239 // match the "hardware" with the lowest layer
2241 SCNetworkInterfaceRef nextInterface
;
2243 nextInterface
= SCNetworkInterfaceGetInterface(interface
);
2244 if (nextInterface
== NULL
) {
2248 interface
= nextInterface
;
2250 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2252 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2253 if (interfaceIndex
!= kCFNotFound
) {
2254 if (configurations
[interfaceIndex
].entity_hardware
!= NULL
) {
2255 CFDictionarySetValue(entity
,
2256 kSCPropNetInterfaceHardware
,
2257 *configurations
[interfaceIndex
].entity_hardware
);
2260 CFDictionarySetValue(entity
,
2261 kSCPropNetInterfaceHardware
,
2262 interfacePrivate
->interface_type
);
2265 // add the localized display name (which will only be used when/if the
2266 // interface is removed from the system)
2267 CFDictionarySetValue(entity
,
2268 kSCPropUserDefinedName
,
2269 SCNetworkInterfaceGetLocalizedDisplayName(interface
));
2271 // note that this is a V.92 capable modem
2272 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeModem
) &&
2273 interfacePrivate
->modemIsV92
) {
2277 num
= CFNumberCreate(NULL
, kCFNumberIntType
, &one
);
2278 CFDictionarySetValue(entity
,
2279 kSCPropNetInterfaceSupportsModemOnHold
,
2288 static SCNetworkInterfaceRef
2289 findInterface(CFArrayRef interfaces
, CFStringRef match_if
)
2294 n
= CFArrayGetCount(interfaces
);
2295 for (i
= 0; i
< n
; i
++) {
2296 SCNetworkInterfaceRef interface
= CFArrayGetValueAtIndex(interfaces
, i
);
2297 CFStringRef interfaceName
;
2299 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
2300 if ((interfaceName
!= NULL
) && CFEqual(interfaceName
, match_if
)) {
2301 CFRetain(interface
);
2310 static SCNetworkInterfaceRef
2311 findBondInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
2314 SCNetworkInterfaceRef interface
= NULL
;
2316 if (prefs
== NULL
) {
2320 // check if the interface is an Ethernet Bond
2321 bonds
= SCBondInterfaceCopyAll(prefs
);
2322 if (bonds
!= NULL
) {
2323 interface
= findInterface(bonds
, ifDevice
);
2329 static SCNetworkInterfaceRef
2330 findVLANInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
2332 SCNetworkInterfaceRef interface
= NULL
;
2335 if (prefs
== NULL
) {
2339 // check if the interface is a VLAN
2340 vlans
= SCVLANInterfaceCopyAll(prefs
);
2341 if (vlans
!= NULL
) {
2342 interface
= findInterface(vlans
, ifDevice
);
2349 SCNetworkInterfaceRef
2350 _SCNetworkInterfaceCreateWithBSDName(CFAllocatorRef allocator
,
2351 CFStringRef bsdName
,
2354 CFMutableDictionaryRef entity
;
2355 SCNetworkInterfaceRef interface
;
2357 entity
= CFDictionaryCreateMutable(NULL
,
2359 &kCFTypeDictionaryKeyCallBacks
,
2360 &kCFTypeDictionaryValueCallBacks
);
2361 CFDictionarySetValue(entity
, kSCPropNetInterfaceDeviceName
, bsdName
);
2362 if ((flags
& kIncludeVLANInterfaces
) == 0) {
2363 CFDictionarySetValue(entity
, CFSTR("_NO_VLAN_INTERFACES_"), kCFBooleanTrue
);
2365 if ((flags
& kIncludeBondInterfaces
) == 0) {
2366 CFDictionarySetValue(entity
, CFSTR("_NO_BOND_INTERFACES_"), kCFBooleanTrue
);
2368 interface
= _SCNetworkInterfaceCreateWithEntity(NULL
, entity
, NULL
);
2375 SCNetworkInterfaceRef
2376 _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef allocator
,
2377 CFDictionaryRef interface_entity
,
2378 SCNetworkServiceRef service
)
2380 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
2381 CFStringRef ifDevice
;
2382 CFStringRef ifSubType
;
2384 CFArrayRef matching_interfaces
= NULL
;
2386 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
2387 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
2389 ifType
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceType
);
2390 if (ifType
== NULL
) {
2392 * The interface "Type" was not specified. We'll make an
2393 * assumption that this is an "Ethernet" interface. If a
2394 * real interface exists with the provided interface name
2395 * then the actual type will be set accordingly. If not, we'll
2396 * end up crafting an "Ethernet" SCNetworkInterface which
2397 * will keep the rest of the configuration APIs happy.
2399 ifType
= kSCValNetInterfaceTypeEthernet
;
2402 if (!isA_CFString(ifType
)) {
2406 ifSubType
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceSubType
);
2407 if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
2408 if (!isA_CFString(ifSubType
)) {
2413 ifDevice
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceDeviceName
);
2415 if (CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
) ||
2416 CFEqual(ifType
, kSCValNetInterfaceTypeFireWire
) ||
2417 (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) && CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPoE
))) {
2418 char bsdName
[IFNAMSIZ
+ 1];
2419 CFMutableDictionaryRef matching
;
2421 if (!isA_CFString(ifDevice
)) {
2425 if (_SC_cfstring_to_cstring(ifDevice
, bsdName
, sizeof(bsdName
), kCFStringEncodingASCII
) == NULL
) {
2429 matching
= IOBSDNameMatching(masterPort
, 0, bsdName
);
2430 if (matching
== NULL
) {
2434 // note: the "matching" dictionary will be consumed by the following
2435 matching_interfaces
= findMatchingInterfaces(matching
, processNetworkInterface
);
2437 } else if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
2438 if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPSerial
)) {
2439 CFDictionaryRef matching
;
2440 CFStringRef match_keys
[2];
2441 CFStringRef match_vals
[2];
2443 if (!isA_CFString(ifDevice
)) {
2447 match_keys
[0] = CFSTR(kIOProviderClassKey
);
2448 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
2450 match_keys
[1] = CFSTR(kIOTTYDeviceKey
);
2451 match_vals
[1] = ifDevice
;
2453 matching
= CFDictionaryCreate(NULL
,
2454 (const void **)match_keys
,
2455 (const void **)match_vals
,
2456 sizeof(match_keys
)/sizeof(match_keys
[0]),
2457 &kCFTypeDictionaryKeyCallBacks
,
2458 &kCFTypeDictionaryValueCallBacks
);
2460 // note: the "matching" dictionary will be consumed by the following
2461 matching_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
);
2463 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypeL2TP
)) {
2464 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
2465 kSCNetworkInterfaceTypeL2TP
);
2466 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPTP
)) {
2467 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
2468 kSCNetworkInterfaceTypePPTP
);
2470 // XXX do we allow non-Apple variants of PPP??? XXX
2471 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
2474 } else if (CFEqual(ifType
, kSCValNetInterfaceType6to4
)) {
2475 if (!isA_CFString(ifDevice
)) {
2479 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
2480 kSCNetworkInterfaceType6to4
);
2481 } else if ((CFStringFind(ifType
, CFSTR("."), 0).location
!= kCFNotFound
) && (ifDevice
== NULL
)) {
2482 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
2486 if (matching_interfaces
!= NULL
) {
2488 SCPreferencesRef prefs
;
2490 n
= CFArrayGetCount(matching_interfaces
);
2493 if (!CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
)) {
2496 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), NULL
);
2497 if (prefs
== NULL
) {
2500 if (!CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_VLAN_INTERFACES_"))) {
2501 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findVLANInterface(prefs
, ifDevice
);
2503 if ((interfacePrivate
== NULL
)
2504 && !CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_BOND_INTERFACES_"))) {
2505 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findBondInterface(prefs
, ifDevice
);
2510 interfacePrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, 0);
2511 CFRetain(interfacePrivate
);
2514 SCLog(TRUE
, LOG_DEBUG
, CFSTR("_SCNetworkInterfaceCreateWithEntity() failed, more than one interface matches %@"), ifDevice
);
2515 CFRelease(matching_interfaces
);
2516 _SCErrorSet(kSCStatusFailed
);
2519 CFRelease(matching_interfaces
);
2524 if (interfacePrivate
== NULL
) {
2526 * if device not present on this system
2528 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
, NULL
);
2529 interfacePrivate
->entity_type
= ifType
;
2530 interfacePrivate
->entity_subtype
= ifSubType
;
2531 interfacePrivate
->entity_device
= (ifDevice
!= NULL
) ? CFStringCreateCopy(NULL
, ifDevice
) : NULL
;
2533 if (CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
)) {
2534 CFStringRef entity_hardware
;
2536 entity_hardware
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceHardware
);
2537 if ((entity_hardware
!= NULL
) &&
2538 CFEqual(entity_hardware
, kSCEntNetAirPort
)) {
2539 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
2541 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
2543 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeFireWire
)) {
2544 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeFireWire
;
2545 } else if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
2546 if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPoE
)) {
2547 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
2548 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPSerial
)) {
2549 if (CFStringHasPrefix(ifDevice
, CFSTR("Bluetooth"))) {
2550 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBluetooth
;
2551 } else if (CFStringHasPrefix(ifDevice
, CFSTR("irda"))) {
2552 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIrDA
;
2553 } else if (CFStringHasPrefix(ifDevice
, CFSTR("wwan"))) {
2554 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeWWAN
;
2556 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeModem
;
2560 CFRelease(interfacePrivate
);
2561 interfacePrivate
= (SCNetworkInterfacePrivateRef
)kSCNetworkInterfaceIPv4
;
2562 CFRetain(interfacePrivate
);
2564 } else if (CFStringFind(ifType
, CFSTR("."), 0).location
!= kCFNotFound
) {
2565 // if vendor interface
2566 interfacePrivate
->interface_type
= ifType
;
2568 // if unknown interface
2569 CFRelease(interfacePrivate
);
2570 interfacePrivate
= NULL
;
2574 if ((interfacePrivate
!= NULL
) && (service
!= NULL
)) {
2575 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)service
;
2577 if (interfacePrivate
->prefs
!= NULL
)
2578 CFRelease(interfacePrivate
->prefs
);
2579 if (interfacePrivate
->serviceID
!= NULL
)
2580 CFRelease(interfacePrivate
->serviceID
);
2582 interfacePrivate
->prefs
= CFRetain(servicePrivate
->prefs
);
2583 interfacePrivate
->serviceID
= CFRetain(servicePrivate
->serviceID
);
2586 if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
2587 SCNetworkInterfaceRef parent
;
2589 parent
= SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef
)interfacePrivate
,
2590 kSCNetworkInterfaceTypePPP
);
2591 CFRelease(interfacePrivate
);
2592 interfacePrivate
= (SCNetworkInterfacePrivateRef
)parent
;
2595 return (SCNetworkInterfaceRef
)interfacePrivate
;
2600 #pragma mark SCNetworkInterface APIs
2605 __SCNetworkInterfaceCopyAll_IONetworkInterface(void)
2607 CFDictionaryRef matching
;
2608 CFArrayRef new_interfaces
;
2610 // get Ethernet, Firewire, and AirPort interfaces
2612 matching
= IOServiceMatching(kIONetworkInterfaceClass
);
2613 new_interfaces
= findMatchingInterfaces(matching
, processNetworkInterface
);
2615 return new_interfaces
;
2621 __SCNetworkInterfaceCopyAll_Modem()
2623 CFDictionaryRef matching
;
2624 CFStringRef match_keys
[2];
2625 CFStringRef match_vals
[2];
2626 CFArrayRef new_interfaces
;
2628 match_keys
[0] = CFSTR(kIOProviderClassKey
);
2629 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
2631 match_keys
[1] = CFSTR(kIOSerialBSDTypeKey
);
2632 match_vals
[1] = CFSTR(kIOSerialBSDModemType
);
2634 matching
= CFDictionaryCreate(NULL
,
2635 (const void **)match_keys
,
2636 (const void **)match_vals
,
2637 sizeof(match_keys
)/sizeof(match_keys
[0]),
2638 &kCFTypeDictionaryKeyCallBacks
,
2639 &kCFTypeDictionaryValueCallBacks
);
2640 new_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
);
2642 return new_interfaces
;
2648 __SCNetworkInterfaceCopyAll_RS232()
2650 CFDictionaryRef matching
;
2651 CFStringRef match_keys
[2];
2652 CFStringRef match_vals
[2];
2653 CFArrayRef new_interfaces
;
2655 match_keys
[0] = CFSTR(kIOProviderClassKey
);
2656 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
2658 match_keys
[1] = CFSTR(kIOSerialBSDTypeKey
);
2659 match_vals
[1] = CFSTR(kIOSerialBSDRS232Type
);
2661 matching
= CFDictionaryCreate(NULL
,
2662 (const void **)match_keys
,
2663 (const void **)match_vals
,
2664 sizeof(match_keys
)/sizeof(match_keys
[0]),
2665 &kCFTypeDictionaryKeyCallBacks
,
2666 &kCFTypeDictionaryValueCallBacks
);
2667 new_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
);
2669 return new_interfaces
;
2674 add_interfaces(CFMutableArrayRef all_interfaces
, CFArrayRef new_interfaces
)
2679 n
= CFArrayGetCount(new_interfaces
);
2680 for (i
= 0; i
< n
; i
++) {
2681 CFStringRef bsdName
;
2682 SCNetworkInterfaceRef interface
;
2684 interface
= CFArrayGetValueAtIndex(new_interfaces
, i
);
2685 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
2686 if (bsdName
!= NULL
) {
2687 CFArrayAppendValue(all_interfaces
, interface
);
2696 __waitForInterfaces()
2701 SCDynamicStoreRef store
;
2703 store
= SCDynamicStoreCreate(NULL
, CFSTR("SCNetworkInterfaceCopyAll"), NULL
, NULL
);
2704 if (store
== NULL
) {
2708 key
= SCDynamicStoreKeyCreate(NULL
, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin
);
2709 keys
= CFArrayCreate(NULL
, (const void **)&key
, 1, &kCFTypeArrayCallBacks
);
2710 ok
= SCDynamicStoreSetNotificationKeys(store
, keys
, NULL
);
2713 SCLog(TRUE
, LOG_ERR
,
2714 CFSTR("SCDynamicStoreSetNotificationKeys() failed: %s"), SCErrorString(SCError()));
2719 CFDictionaryRef dict
;
2720 Boolean quiet
= FALSE
;
2723 dict
= SCDynamicStoreCopyValue(store
, key
);
2725 if (isA_CFDictionary(dict
) &&
2726 (CFDictionaryContainsKey(dict
, CFSTR("*QUIET*")) ||
2727 CFDictionaryContainsKey(dict
, CFSTR("*TIMEOUT*")))) {
2736 ok
= SCDynamicStoreNotifyWait(store
);
2738 SCLog(TRUE
, LOG_ERR
,
2739 CFSTR("SCDynamicStoreNotifyWait() failed: %s"), SCErrorString(SCError()));
2752 CFArrayRef
/* of SCNetworkInterfaceRef's */
2753 SCNetworkInterfaceCopyAll()
2755 CFMutableArrayRef all_interfaces
;
2756 CFArrayRef new_interfaces
;
2757 SCPreferencesRef prefs
;
2759 /* initialize runtime */
2760 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
2762 /* wait for IOKit to quiesce */
2763 pthread_once(&iokit_quiet
, __waitForInterfaces
);
2765 all_interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2767 // get Ethernet, Firewire, and AirPort interfaces
2768 new_interfaces
= __SCNetworkInterfaceCopyAll_IONetworkInterface();
2769 if (new_interfaces
!= NULL
) {
2770 add_interfaces(all_interfaces
, new_interfaces
);
2771 CFRelease(new_interfaces
);
2774 // get Modem interfaces
2775 new_interfaces
= __SCNetworkInterfaceCopyAll_Modem();
2776 if (new_interfaces
!= NULL
) {
2777 add_interfaces(all_interfaces
, new_interfaces
);
2778 CFRelease(new_interfaces
);
2781 // get serial (RS232) interfaces
2782 new_interfaces
= __SCNetworkInterfaceCopyAll_RS232();
2783 if (new_interfaces
!= NULL
) {
2784 add_interfaces(all_interfaces
, new_interfaces
);
2785 CFRelease(new_interfaces
);
2788 // get virtual network interfaces (Bond, VLAN)
2789 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterfaceCopyAll"), NULL
);
2790 if (prefs
!= NULL
) {
2791 new_interfaces
= SCBondInterfaceCopyAll(prefs
);
2792 if (new_interfaces
!= NULL
) {
2793 add_interfaces(all_interfaces
, new_interfaces
);
2794 CFRelease(new_interfaces
);
2797 new_interfaces
= SCVLANInterfaceCopyAll(prefs
);
2798 if (new_interfaces
!= NULL
) {
2799 add_interfaces(all_interfaces
, new_interfaces
);
2800 CFRelease(new_interfaces
);
2806 // all interfaces have been identified, order and return
2807 sort_interfaces(all_interfaces
);
2809 return all_interfaces
;
2813 CFArrayRef
/* of kSCNetworkInterfaceTypeXXX CFStringRef's */
2814 SCNetworkInterfaceGetSupportedInterfaceTypes(SCNetworkInterfaceRef interface
)
2817 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2819 if (!isA_SCNetworkInterface(interface
)) {
2820 _SCErrorSet(kSCStatusInvalidArgument
);
2824 if (interfacePrivate
->supported_interface_types
!= NULL
) {
2828 i
= findConfiguration(interfacePrivate
->interface_type
);
2829 if (i
!= kCFNotFound
) {
2830 if (configurations
[i
].supported_interfaces
!= doNone
) {
2831 interfacePrivate
->supported_interface_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2832 if (configurations
[i
].supported_interfaces
& do6to4
) {
2833 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceType6to4
);
2835 if (configurations
[i
].supported_interfaces
& doL2TP
) {
2836 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeL2TP
);
2838 if (configurations
[i
].supported_interfaces
& doPPP
) {
2839 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypePPP
);
2841 if (configurations
[i
].supported_interfaces
& doPPTP
) {
2842 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypePPTP
);
2849 return interfacePrivate
->supported_interface_types
;
2853 CFArrayRef
/* of kSCNetworkProtocolTypeXXX CFStringRef's */
2854 SCNetworkInterfaceGetSupportedProtocolTypes(SCNetworkInterfaceRef interface
)
2857 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2859 if (!isA_SCNetworkInterface(interface
)) {
2860 _SCErrorSet(kSCStatusInvalidArgument
);
2864 if (interfacePrivate
->supported_protocol_types
!= NULL
) {
2868 i
= findConfiguration(interfacePrivate
->interface_type
);
2869 if (i
!= kCFNotFound
) {
2870 if (configurations
[i
].supported_protocols
!= doNone
) {
2871 interfacePrivate
->supported_protocol_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2872 if (configurations
[i
].supported_protocols
& doAppleTalk
) {
2873 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeAppleTalk
);
2875 if (configurations
[i
].supported_protocols
& doDNS
) {
2876 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeDNS
);
2878 if (configurations
[i
].supported_protocols
& doIPv4
) {
2879 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeIPv4
);
2881 if (configurations
[i
].supported_protocols
& doIPv6
) {
2882 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeIPv6
);
2884 if (configurations
[i
].supported_protocols
& doProxies
) {
2885 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeProxies
);
2887 if (configurations
[i
].supported_protocols
& doSMB
) {
2888 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeSMB
);
2895 return interfacePrivate
->supported_protocol_types
;
2899 SCNetworkInterfaceRef
2900 SCNetworkInterfaceCreateWithInterface(SCNetworkInterfaceRef child
, CFStringRef interfaceType
)
2902 SCNetworkInterfacePrivateRef childPrivate
= (SCNetworkInterfacePrivateRef
)child
;
2904 SCNetworkInterfacePrivateRef parentPrivate
;
2906 if (!isA_SCNetworkInterface(child
)) {
2907 _SCErrorSet(kSCStatusInvalidArgument
);
2911 if (!isA_CFString(interfaceType
)) {
2912 _SCErrorSet(kSCStatusInvalidArgument
);
2916 childIndex
= findConfiguration(childPrivate
->interface_type
);
2918 parentPrivate
= __SCNetworkInterfaceCreatePrivate(NULL
,
2920 childPrivate
->prefs
,
2921 childPrivate
->serviceID
,
2923 if (parentPrivate
== NULL
) {
2924 _SCErrorSet(kSCStatusFailed
);
2928 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
2929 parentPrivate
->interface_type
= kSCNetworkInterfaceTypePPP
;
2930 parentPrivate
->entity_type
= kSCEntNetPPP
;
2933 if (childIndex
!= kCFNotFound
) {
2934 if (configurations
[childIndex
].ppp_subtype
!= NULL
) {
2935 parentPrivate
->entity_subtype
= *configurations
[childIndex
].ppp_subtype
;
2937 // sorry, the child interface does not support PPP
2941 // if the child's interface type not known, use the child entities "Type"
2942 parentPrivate
->entity_subtype
= childPrivate
->entity_type
;
2945 if (childPrivate
->entity_device
!= NULL
) {
2946 parentPrivate
->entity_device
= CFStringCreateCopy(NULL
, childPrivate
->entity_device
);
2948 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
2949 if ((childIndex
== kCFNotFound
) ||
2950 ((configurations
[childIndex
].supported_interfaces
& doL2TP
) != doL2TP
)) {
2951 // if the child interface does not support L2TP
2954 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeL2TP
;
2955 parentPrivate
->localized_key
= CFSTR("l2tp");
2956 parentPrivate
->entity_type
= kSCValNetInterfaceSubTypeL2TP
; // interface config goes into "L2TP"
2957 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPTP
)) {
2958 if ((childIndex
== kCFNotFound
) ||
2959 ((configurations
[childIndex
].supported_interfaces
& doPPTP
) != doPPTP
)) {
2960 // if the child interface does not support PPTP
2963 parentPrivate
->interface_type
= kSCNetworkInterfaceTypePPTP
;
2964 parentPrivate
->localized_key
= CFSTR("pptp");
2965 parentPrivate
->entity_type
= kSCValNetInterfaceSubTypePPTP
; // interface config goes into "PPTP"
2966 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceType6to4
)) {
2967 if ((childIndex
== kCFNotFound
) ||
2968 ((configurations
[childIndex
].supported_interfaces
& do6to4
) != do6to4
)) {
2969 // if the child interface does not support 6to4
2973 parentPrivate
->interface_type
= kSCNetworkInterfaceType6to4
;
2974 parentPrivate
->localized_key
= CFSTR("6to4");
2975 parentPrivate
->entity_type
= kSCEntNet6to4
;
2976 parentPrivate
->entity_device
= CFRetain(CFSTR("stf0"));
2977 } else if (CFStringFind(interfaceType
, CFSTR("."), 0).location
!= kCFNotFound
) {
2978 // if custom interface type
2979 parentPrivate
->interface_type
= interfaceType
;
2980 parentPrivate
->entity_type
= interfaceType
; // interface config goes into a
2981 // a dictionary with the same
2982 // name as the interfaceType
2984 // unknown interface type
2988 if (childPrivate
->overrides
!= NULL
) {
2989 parentPrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, childPrivate
->overrides
);
2991 parentPrivate
->sort_order
= childPrivate
->sort_order
;
2993 return (SCNetworkInterfaceRef
)parentPrivate
;
2997 CFRelease(parentPrivate
);
2998 _SCErrorSet(kSCStatusInvalidArgument
);
3003 static CFDictionaryRef
3004 __SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface
,
3005 CFStringRef extendedType
)
3007 CFDictionaryRef config
= NULL
;
3008 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3011 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
3012 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
3014 paths
= copyConfigurationPaths(interfacePrivate
, extendedType
);
3015 if (paths
!= NULL
) {
3018 path
= CFArrayGetValueAtIndex(paths
, 0);
3019 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
3023 if (interfacePrivate
->unsaved
!= NULL
) {
3024 config
= CFDictionaryGetValue(interfacePrivate
->unsaved
, extendedType
);
3025 if (config
== (CFDictionaryRef
)kCFNull
) {
3031 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
3040 SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface
)
3042 CFDictionaryRef config
;
3043 CFStringRef defaultType
;
3045 if (!isA_SCNetworkInterface(interface
)) {
3046 _SCErrorSet(kSCStatusInvalidArgument
);
3050 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
3051 if (defaultType
== NULL
) {
3055 config
= __SCNetworkInterfaceGetConfiguration(interface
, defaultType
);
3056 if (config
== NULL
) {
3057 if (CFEqual(defaultType
, kSCEntNetAirPort
)) {
3058 SCNetworkInterfacePrivateRef interfacePrivate
;
3061 // if AirPort interface, check for a per-service config
3062 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3063 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
3064 interfacePrivate
->serviceID
, // service
3065 kSCEntNetAirPort
); // entity
3066 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
3070 if (config
== NULL
) {
3071 _SCErrorSet(kSCStatusOK
);
3079 SCNetworkInterfaceGetExtendedConfiguration(SCNetworkInterfaceRef interface
,
3080 CFStringRef extendedType
)
3082 CFDictionaryRef config
;
3084 if (!isA_SCNetworkInterface(interface
)) {
3085 _SCErrorSet(kSCStatusInvalidArgument
);
3089 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, TRUE
)) {
3090 _SCErrorSet(kSCStatusInvalidArgument
);
3094 config
= __SCNetworkInterfaceGetConfiguration(interface
, extendedType
);
3095 if (config
== NULL
) {
3096 _SCErrorSet(kSCStatusOK
);
3104 SCNetworkInterfaceGetBSDName(SCNetworkInterfaceRef interface
)
3106 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3108 if (!isA_SCNetworkInterface(interface
)) {
3109 _SCErrorSet(kSCStatusInvalidArgument
);
3113 if ((interfacePrivate
->interface
!= NULL
) &&
3114 (interfacePrivate
->interface
!= kSCNetworkInterfaceIPv4
)) {
3115 _SCErrorSet(kSCStatusOK
);
3119 return interfacePrivate
->entity_device
;
3124 SCNetworkInterfaceGetHardwareAddressString(SCNetworkInterfaceRef interface
)
3126 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3128 if (!isA_SCNetworkInterface(interface
)) {
3129 _SCErrorSet(kSCStatusInvalidArgument
);
3133 if ((interfacePrivate
->address
!= NULL
) &&
3134 (interfacePrivate
->addressString
== NULL
)) {
3138 char mac
[sizeof("xx:xx:xx:xx:xx:xx:xx:xx")];
3141 bp
= (uint8_t *)CFDataGetBytePtr(interfacePrivate
->address
);
3142 n
= CFDataGetLength(interfacePrivate
->address
) * 3;
3144 if (n
> sizeof(mac
)) {
3145 mac_p
= CFAllocatorAllocate(NULL
, 0, n
);
3148 for (cp
= mac_p
; n
> 0; n
-= 3) {
3149 cp
+= snprintf(cp
, n
, "%2.2x:", *bp
++);
3152 interfacePrivate
->addressString
= CFStringCreateWithCString(NULL
, mac_p
, kCFStringEncodingUTF8
);
3153 if (mac_p
!= mac
) CFAllocatorDeallocate(NULL
, mac_p
);
3156 return interfacePrivate
->addressString
;
3160 SCNetworkInterfaceRef
3161 SCNetworkInterfaceGetInterface(SCNetworkInterfaceRef interface
)
3163 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3165 if (!isA_SCNetworkInterface(interface
)) {
3166 _SCErrorSet(kSCStatusInvalidArgument
);
3170 return interfacePrivate
->interface
;
3175 SCNetworkInterfaceGetInterfaceType(SCNetworkInterfaceRef interface
)
3177 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3179 if (!isA_SCNetworkInterface(interface
)) {
3180 _SCErrorSet(kSCStatusInvalidArgument
);
3184 return interfacePrivate
->interface_type
;
3189 copy_interface_string(CFBundleRef bundle
, CFStringRef key
, Boolean localized
)
3191 CFStringRef str
= NULL
;
3194 str
= CFBundleCopyLocalizedString(bundle
,
3197 NETWORKINTERFACE_LOCALIZATIONS
);
3199 str
= _SC_CFBundleCopyNonLocalizedString(bundle
,
3202 NETWORKINTERFACE_LOCALIZATIONS
);
3210 copy_display_name(SCNetworkInterfaceRef interface
, Boolean localized
)
3212 CFMutableStringRef local
;
3215 local
= CFStringCreateMutable(NULL
, 0);
3217 while (interface
!= NULL
) {
3218 Boolean added
= FALSE
;
3219 SCNetworkInterfaceRef child
= NULL
;
3220 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3222 if ((interfacePrivate
->interface
!= NULL
) &&
3223 (interfacePrivate
->interface
!= kSCNetworkInterfaceIPv4
)) {
3224 child
= interfacePrivate
->interface
;
3227 if ((bundle
!= NULL
) && (interfacePrivate
->localized_key
!= NULL
)) {
3230 fmt
= copy_interface_string(bundle
, interfacePrivate
->localized_key
, localized
);
3232 CFStringAppendFormat(local
,
3235 interfacePrivate
->localized_arg1
,
3236 interfacePrivate
->localized_arg2
);
3243 (interfacePrivate
->prefs
!= NULL
) &&
3244 (interfacePrivate
->serviceID
!= NULL
) &&
3246 CFDictionaryRef entity
;
3249 // check for (and use) the name of the interface when it
3250 // was last available
3251 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,
3252 interfacePrivate
->serviceID
,
3253 kSCEntNetInterface
);
3254 entity
= SCPreferencesPathGetValue(interfacePrivate
->prefs
, path
);
3256 if (isA_CFDictionary(entity
)) {
3259 name
= CFDictionaryGetValue(entity
, kSCPropUserDefinedName
);
3260 if (isA_CFString(name
)) {
3261 CFStringAppend(local
, name
);
3268 // create (non-)localized name based on the interface type
3269 CFStringAppend(local
, interfacePrivate
->interface_type
);
3271 // ... and, if this is a leaf node, the interface device
3272 if ((interfacePrivate
->entity_device
!= NULL
) && (child
== NULL
)) {
3273 CFStringAppendFormat(local
, NULL
, CFSTR(" (%@)"), interfacePrivate
->entity_device
);
3277 if (child
!= NULL
) {
3278 // if this interface is layered over another
3279 CFStringAppend(local
, CFSTR(" --> "));
3285 name
= CFStringCreateCopy(NULL
, local
);
3294 __SCNetworkInterfaceGetNonLocalizedDisplayName(SCNetworkInterfaceRef interface
)
3296 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3298 if (!isA_SCNetworkInterface(interface
)) {
3299 _SCErrorSet(kSCStatusInvalidArgument
);
3303 if (interfacePrivate
->name
== NULL
) {
3304 interfacePrivate
->name
= copy_display_name(interface
, FALSE
);
3307 return interfacePrivate
->name
;
3312 SCNetworkInterfaceGetLocalizedDisplayName(SCNetworkInterfaceRef interface
)
3314 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3316 if (!isA_SCNetworkInterface(interface
)) {
3317 _SCErrorSet(kSCStatusInvalidArgument
);
3321 if (interfacePrivate
->localized_name
== NULL
) {
3322 interfacePrivate
->localized_name
= copy_display_name(interface
, TRUE
);
3325 return interfacePrivate
->localized_name
;
3331 __SCNetworkInterfaceGetTemplateOverrides(SCNetworkInterfaceRef interface
, CFStringRef interfaceType
)
3333 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3334 CFDictionaryRef overrides
= NULL
;
3336 if (interfacePrivate
->overrides
!= NULL
) {
3337 overrides
= CFDictionaryGetValue(interfacePrivate
->overrides
, interfaceType
);
3345 SCNetworkInterfaceGetTypeID(void)
3347 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
); /* initialize runtime */
3348 return __kSCNetworkInterfaceTypeID
;
3354 __SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface
,
3355 CFStringRef extendedType
,
3356 CFDictionaryRef config
,
3359 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3363 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
3364 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
3366 if (extendedType
== NULL
) {
3367 extendedType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
3368 if (extendedType
== NULL
) {
3373 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
3377 paths
= copyConfigurationPaths(interfacePrivate
, extendedType
);
3378 if (paths
!= NULL
) {
3382 n
= CFArrayGetCount(paths
);
3383 for (i
= 0; i
< n
; i
++) {
3386 path
= CFArrayGetValueAtIndex(paths
, i
);
3387 ok
= __setPrefsConfiguration(interfacePrivate
->prefs
, path
, config
, FALSE
);
3394 // if configuration has been saved
3395 if (interfacePrivate
->unsaved
!= NULL
) {
3396 CFDictionaryRemoveValue(interfacePrivate
->unsaved
, extendedType
);
3397 if (CFDictionaryGetCount(interfacePrivate
->unsaved
) == 0) {
3398 CFRelease(interfacePrivate
->unsaved
);
3399 interfacePrivate
->unsaved
= NULL
;
3407 if (config
== NULL
) {
3408 // remember that we are clearing the configuration
3409 config
= (CFDictionaryRef
)kCFNull
;
3412 if (interfacePrivate
->unsaved
== NULL
) {
3413 interfacePrivate
->unsaved
= CFDictionaryCreateMutable(NULL
,
3415 &kCFTypeDictionaryKeyCallBacks
,
3416 &kCFTypeDictionaryValueCallBacks
);
3418 CFDictionarySetValue(interfacePrivate
->unsaved
, extendedType
, config
);
3421 _SCErrorSet(kSCStatusNoKey
);
3430 SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface
, CFDictionaryRef config
)
3432 CFStringRef defaultType
;
3434 if (!isA_SCNetworkInterface(interface
)) {
3435 _SCErrorSet(kSCStatusInvalidArgument
);
3439 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
3440 if (defaultType
== NULL
) {
3444 return __SCNetworkInterfaceSetConfiguration(interface
, defaultType
, config
, FALSE
);
3449 SCNetworkInterfaceSetExtendedConfiguration(SCNetworkInterfaceRef interface
,
3450 CFStringRef extendedType
,
3451 CFDictionaryRef config
)
3453 if (!isA_SCNetworkInterface(interface
)) {
3454 _SCErrorSet(kSCStatusInvalidArgument
);
3458 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, TRUE
)) {
3462 return __SCNetworkInterfaceSetConfiguration(interface
, extendedType
, config
, FALSE
);
3467 #pragma mark SCNetworkInterface [Refresh Configuration] API
3470 #ifndef kSCEntNetRefreshConfiguration
3471 #define kSCEntNetRefreshConfiguration CFSTR("RefreshConfiguration")
3472 #endif // kSCEntNetRefreshConfiguration
3475 _SCNetworkInterfaceForceConfigurationRefresh(CFStringRef ifName
)
3479 SCDynamicStoreRef store
;
3481 if (!isA_CFString(ifName
)) {
3482 _SCErrorSet(kSCStatusInvalidArgument
);
3486 store
= SCDynamicStoreCreate(NULL
, CFSTR("_SCNetworkInterfaceForceConfigurationRefresh"), NULL
, NULL
);
3487 if (store
== NULL
) {
3491 key
= SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL
,
3492 kSCDynamicStoreDomainState
,
3494 kSCEntNetRefreshConfiguration
);
3495 ok
= SCDynamicStoreNotifyValue(store
, key
);
3503 __SCNetworkInterfaceForceConfigurationRefresh_helper(SCPreferencesRef prefs
, CFStringRef ifName
)
3505 CFDataRef data
= NULL
;
3507 SCPreferencesPrivateRef prefsPrivate
= (SCPreferencesPrivateRef
)prefs
;
3508 uint32_t status
= kSCStatusOK
;
3509 CFDataRef reply
= NULL
;
3511 if (prefsPrivate
->helper
== -1) {
3512 ok
= __SCPreferencesCreate_helper(prefs
);
3518 // serialize the interface name
3519 ok
= _SCSerializeString(ifName
, &data
, NULL
, NULL
);
3524 // have the helper "refresh" the configuration
3525 status
= kSCStatusOK
;
3527 ok
= _SCHelperExec(prefsPrivate
->helper
,
3528 SCHELPER_MSG_INTERFACE_REFRESH
,
3532 if (data
!= NULL
) CFRelease(data
);
3537 if (status
!= kSCStatusOK
) {
3546 if (prefsPrivate
->helper
!= -1) {
3547 _SCHelperClose(prefsPrivate
->helper
);
3548 prefsPrivate
->helper
= -1;
3551 status
= kSCStatusAccessError
;
3556 _SCErrorSet(status
);
3562 SCNetworkInterfaceForceConfigurationRefresh(SCNetworkInterfaceRef interface
)
3565 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3567 if (!isA_SCNetworkInterface(interface
)) {
3568 _SCErrorSet(kSCStatusInvalidArgument
);
3572 ifName
= SCNetworkInterfaceGetBSDName(interface
);
3573 if (ifName
== NULL
) {
3574 _SCErrorSet(kSCStatusInvalidArgument
);
3578 if (interfacePrivate
->prefs
!= NULL
) {
3579 SCPreferencesRef prefs
= interfacePrivate
->prefs
;
3580 SCPreferencesPrivateRef prefsPrivate
= (SCPreferencesPrivateRef
)prefs
;
3582 if (prefsPrivate
->authorizationData
!= NULL
) {
3583 return __SCNetworkInterfaceForceConfigurationRefresh_helper(prefs
, ifName
);
3587 return _SCNetworkInterfaceForceConfigurationRefresh(ifName
);
3592 SCNetworkInterfaceRefreshConfiguration(CFStringRef ifName
)
3594 return _SCNetworkInterfaceForceConfigurationRefresh(ifName
);
3599 #pragma mark SCNetworkInterface Password APIs
3603 getPasswordID(CFDictionaryRef config
, CFStringRef serviceID
)
3605 CFStringRef unique_id
= NULL
;
3607 if (config
!= NULL
) {
3608 CFStringRef encryption
;
3610 encryption
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPasswordEncryption
);
3611 if (isA_CFString(encryption
) &&
3612 CFEqual(encryption
, kSCValNetPPPAuthPasswordEncryptionKeychain
)) {
3613 unique_id
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPassword
);
3616 if (unique_id
== NULL
) {
3617 unique_id
= serviceID
;
3625 copySharedSecretID(CFDictionaryRef config
, CFStringRef serviceID
)
3627 CFMutableStringRef sharedSecret
= NULL
;
3629 if (config
!= NULL
) {
3630 CFStringRef encryption
;
3632 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecretEncryption
);
3633 if (isA_CFString(encryption
) &&
3634 CFEqual(encryption
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) {
3635 sharedSecret
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecret
);
3636 if (sharedSecret
!= NULL
) {
3637 CFRetain(sharedSecret
);
3642 if (sharedSecret
== NULL
) {
3643 CFStringRef unique_id
;
3645 unique_id
= getPasswordID(config
, serviceID
);
3646 sharedSecret
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
3647 CFStringAppend(sharedSecret
, CFSTR(".SS"));
3650 return sharedSecret
;
3655 checkInterfacePassword(SCNetworkInterfaceRef interface
,
3656 SCNetworkInterfacePasswordType passwordType
,
3657 SCPreferencesRef
*prefs
,
3658 CFStringRef
*serviceID
)
3660 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3662 if (!isA_SCNetworkInterface(interface
)) {
3663 _SCErrorSet(kSCStatusInvalidArgument
);
3667 *serviceID
= interfacePrivate
->serviceID
;
3668 if (*serviceID
== NULL
) {
3669 _SCErrorSet(kSCStatusInvalidArgument
);
3673 *prefs
= interfacePrivate
->prefs
;
3674 if (*prefs
== NULL
) {
3675 _SCErrorSet(kSCStatusInvalidArgument
);
3679 switch (passwordType
) {
3680 case kSCNetworkInterfacePasswordTypePPP
: {
3681 CFStringRef interfaceType
;
3683 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
3684 if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
3685 _SCErrorSet(kSCStatusInvalidArgument
);
3691 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
3692 CFStringRef interfaceType
;
3694 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
3695 if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
3696 _SCErrorSet(kSCStatusInvalidArgument
);
3700 interface
= SCNetworkInterfaceGetInterface(interface
);
3701 if (interface
== NULL
) {
3702 _SCErrorSet(kSCStatusInvalidArgument
);
3706 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
3707 if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
3708 _SCErrorSet(kSCStatusInvalidArgument
);
3714 case kSCNetworkInterfacePasswordTypeEAPOL
: {
3727 SCNetworkInterfaceCheckPassword(SCNetworkInterfaceRef interface
,
3728 SCNetworkInterfacePasswordType passwordType
)
3730 Boolean exists
= FALSE
;
3731 SCPreferencesRef prefs
= NULL
;
3732 CFStringRef serviceID
= NULL
;
3734 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
3738 switch (passwordType
) {
3739 case kSCNetworkInterfacePasswordTypePPP
: {
3740 CFDictionaryRef config
;
3741 CFStringRef unique_id
;
3743 // get configuration
3744 config
= SCNetworkInterfaceGetConfiguration(interface
);
3747 unique_id
= getPasswordID(config
, serviceID
);
3750 exists
= __extract_password(prefs
,
3752 kSCPropNetPPPAuthPassword
,
3753 kSCPropNetPPPAuthPasswordEncryption
,
3754 kSCValNetPPPAuthPasswordEncryptionKeychain
,
3760 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
3761 CFDictionaryRef config
;
3762 CFStringRef shared_id
;
3764 // get configuration
3765 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
3767 // get sharedSecret ID
3768 shared_id
= copySharedSecretID(config
, serviceID
);
3771 exists
= __extract_password(prefs
,
3773 kSCPropNetIPSecSharedSecret
,
3774 kSCPropNetIPSecSharedSecretEncryption
,
3775 kSCValNetIPSecSharedSecretEncryptionKeychain
,
3778 CFRelease(shared_id
);
3782 case kSCNetworkInterfacePasswordTypeEAPOL
: {
3783 CFDictionaryRef config
;
3784 CFStringRef unique_id
= NULL
;
3786 // get configuration
3787 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
3789 // get 802.1X identifier
3790 if (config
!= NULL
) {
3791 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
3793 if (!isA_CFString(unique_id
)) {
3798 exists
= _SCPreferencesSystemKeychainPasswordItemExists(prefs
, unique_id
);
3803 _SCErrorSet(kSCStatusInvalidArgument
);
3812 SCNetworkInterfaceCopyPassword(SCNetworkInterfaceRef interface
,
3813 SCNetworkInterfacePasswordType passwordType
)
3815 CFDataRef password
= NULL
;
3816 SCPreferencesRef prefs
= NULL
;
3817 CFStringRef serviceID
= NULL
;
3819 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
3823 switch (passwordType
) {
3824 case kSCNetworkInterfacePasswordTypePPP
: {
3825 CFDictionaryRef config
;
3826 CFStringRef unique_id
;
3828 // get configuration
3829 config
= SCNetworkInterfaceGetConfiguration(interface
);
3832 unique_id
= getPasswordID(config
, serviceID
);
3835 (void) __extract_password(prefs
,
3837 kSCPropNetPPPAuthPassword
,
3838 kSCPropNetPPPAuthPasswordEncryption
,
3839 kSCValNetPPPAuthPasswordEncryptionKeychain
,
3845 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
3846 CFDictionaryRef config
;
3847 CFStringRef shared_id
;
3849 // get configuration
3850 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
3852 // get sharedSecret ID
3853 shared_id
= copySharedSecretID(config
, serviceID
);
3856 (void) __extract_password(prefs
,
3858 kSCPropNetIPSecSharedSecret
,
3859 kSCPropNetIPSecSharedSecretEncryption
,
3860 kSCValNetIPSecSharedSecretEncryptionKeychain
,
3864 CFRelease(shared_id
);
3868 case kSCNetworkInterfacePasswordTypeEAPOL
: {
3869 CFDictionaryRef config
;
3870 CFStringRef unique_id
= NULL
;
3872 // get configuration
3873 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
3875 // get 802.1X identifier
3876 if (config
!= NULL
) {
3877 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
3879 if (!isA_CFString(unique_id
)) {
3880 _SCErrorSet(kSCStatusFailed
);
3885 password
= _SCPreferencesSystemKeychainPasswordItemCopy(prefs
, unique_id
);
3890 _SCErrorSet(kSCStatusInvalidArgument
);
3899 SCNetworkInterfaceRemovePassword(SCNetworkInterfaceRef interface
,
3900 SCNetworkInterfacePasswordType passwordType
)
3903 SCPreferencesRef prefs
= NULL
;
3904 CFStringRef serviceID
= NULL
;
3906 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
3910 switch (passwordType
) {
3911 case kSCNetworkInterfacePasswordTypePPP
: {
3912 CFDictionaryRef config
;
3913 CFStringRef unique_id
;
3915 // get configuration
3916 config
= SCNetworkInterfaceGetConfiguration(interface
);
3919 unique_id
= getPasswordID(config
, serviceID
);
3922 ok
= _SCPreferencesSystemKeychainPasswordItemRemove(prefs
, unique_id
);
3924 CFMutableDictionaryRef newConfig
;
3926 if (config
!= NULL
) {
3927 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
3928 CFDictionaryRemoveValue(newConfig
, kSCPropNetPPPAuthPassword
);
3929 CFDictionaryRemoveValue(newConfig
, kSCPropNetPPPAuthPasswordEncryption
);
3930 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
3931 CFRelease(newConfig
);
3937 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
3938 CFDictionaryRef config
;
3939 CFStringRef shared_id
;
3941 // get configuration
3942 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
3944 // get sharedSecret ID
3945 shared_id
= copySharedSecretID(config
, serviceID
);
3948 ok
= _SCPreferencesSystemKeychainPasswordItemRemove(prefs
, shared_id
);
3950 CFMutableDictionaryRef newConfig
;
3952 if (config
!= NULL
) {
3953 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
3954 CFDictionaryRemoveValue(newConfig
, kSCPropNetIPSecSharedSecret
);
3955 CFDictionaryRemoveValue(newConfig
, kSCPropNetIPSecSharedSecretEncryption
);
3956 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
3959 CFRelease(newConfig
);
3963 CFRelease(shared_id
);
3967 case kSCNetworkInterfacePasswordTypeEAPOL
: {
3968 CFDictionaryRef config
;
3969 CFStringRef unique_id
= NULL
;
3971 // get configuration
3972 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
3974 // get 802.1X identifier
3975 if (config
!= NULL
) {
3976 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
3978 if (!isA_CFString(unique_id
)) {
3979 _SCErrorSet(kSCStatusFailed
);
3984 ok
= _SCPreferencesSystemKeychainPasswordItemRemove(prefs
, unique_id
);
3989 _SCErrorSet(kSCStatusInvalidArgument
);
3998 SCNetworkInterfaceSetPassword(SCNetworkInterfaceRef interface
,
3999 SCNetworkInterfacePasswordType passwordType
,
4001 CFDictionaryRef options
)
4003 CFStringRef account
= NULL
;
4004 CFDictionaryRef config
;
4005 CFStringRef description
= NULL
;
4006 CFStringRef label
= NULL
;
4008 SCPreferencesRef prefs
= NULL
;
4009 CFStringRef serviceID
= NULL
;
4011 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
4015 switch (passwordType
) {
4016 case kSCNetworkInterfacePasswordTypePPP
: {
4017 SCNetworkServiceRef service
= NULL
;
4018 CFStringRef unique_id
;
4020 // get configuration
4021 config
= SCNetworkInterfaceGetConfiguration(interface
);
4024 unique_id
= getPasswordID(config
, serviceID
);
4026 // get "Account", "Name", "Kind"
4027 if (config
!= NULL
) {
4028 // auth name --> keychain "Account"
4029 account
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthName
);
4031 // PPP [user defined] "name" --> keychain "Name"
4032 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
4035 if (label
== NULL
) {
4036 // service name --> keychain "Name"
4037 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
4042 label
= SCNetworkServiceGetName(service
);
4043 if (label
== NULL
) {
4044 // interface name --> keychain "Name"
4045 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
4049 if (bundle
!= NULL
) {
4050 // "PPP Password" --> keychain "Kind"
4051 description
= CFBundleCopyLocalizedString(bundle
,
4052 CFSTR("KEYCHAIN_PPP_PASSWORD"),
4053 CFSTR("PPP Password"),
4058 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
4060 (label
!= NULL
) ? label
: CFSTR("PPP"),
4061 (description
!= NULL
) ? description
: CFSTR("PPP Password"),
4066 CFMutableDictionaryRef newConfig
;
4068 if (config
!= NULL
) {
4069 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
4071 newConfig
= CFDictionaryCreateMutable(NULL
,
4073 &kCFTypeDictionaryKeyCallBacks
,
4074 &kCFTypeDictionaryValueCallBacks
);
4076 CFDictionarySetValue(newConfig
,
4077 kSCPropNetPPPAuthPassword
,
4079 CFDictionarySetValue(newConfig
,
4080 kSCPropNetPPPAuthPasswordEncryption
,
4081 kSCValNetPPPAuthPasswordEncryptionKeychain
);
4082 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
4083 CFRelease(newConfig
);
4086 if (description
!= NULL
) CFRelease(description
);
4087 if (service
!= NULL
) CFRelease(service
);
4091 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
4092 SCNetworkServiceRef service
= NULL
;
4093 CFStringRef shared_id
;
4095 // get configuration
4096 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
4098 // get sharedSecret ID
4099 shared_id
= copySharedSecretID(config
, serviceID
);
4101 // get "Name", "Kind"
4102 if (config
!= NULL
) {
4103 // PPP [user defined] "name" --> keychain "Name"
4104 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
4107 if (label
== NULL
) {
4108 // service name --> keychain "Name"
4109 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
4114 label
= SCNetworkServiceGetName(service
);
4115 if (label
== NULL
) {
4116 // interface name --> keychain "Name"
4117 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
4121 if (bundle
!= NULL
) {
4122 // "IPSec Shared Secret" --> keychain "Kind"
4123 description
= CFBundleCopyLocalizedString(bundle
,
4124 CFSTR("KEYCHAIN_IPSEC_SHARED_SECRET"),
4125 CFSTR("IPSec Shared Secret"),
4130 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
4132 (label
!= NULL
) ? label
: CFSTR("PPP"),
4133 (description
!= NULL
) ? description
: CFSTR("IPSec Shared Secret"),
4138 CFMutableDictionaryRef newConfig
= NULL
;
4140 if (config
!= NULL
) {
4141 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
4143 newConfig
= CFDictionaryCreateMutable(NULL
,
4145 &kCFTypeDictionaryKeyCallBacks
,
4146 &kCFTypeDictionaryValueCallBacks
);
4148 CFDictionarySetValue(newConfig
,
4149 kSCPropNetIPSecSharedSecret
,
4151 CFDictionarySetValue(newConfig
,
4152 kSCPropNetIPSecSharedSecretEncryption
,
4153 kSCValNetIPSecSharedSecretEncryptionKeychain
);
4154 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
4157 CFRelease(newConfig
);
4160 if (description
!= NULL
) CFRelease(description
);
4161 if (service
!= NULL
) CFRelease(service
);
4162 CFRelease(shared_id
);
4166 case kSCNetworkInterfacePasswordTypeEAPOL
: {
4167 CFStringRef unique_id
= NULL
;
4169 // get configuration
4170 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
4172 // get 802.1X identifier
4173 if (config
!= NULL
) {
4174 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
4176 if (isA_CFString(unique_id
)) {
4177 CFRetain(unique_id
);
4181 uuid
= CFUUIDCreate(NULL
);
4182 unique_id
= CFUUIDCreateString(NULL
, uuid
);
4186 // get "Name", "Kind"
4187 if (bundle
!= NULL
) {
4188 // "802.1X Password" --> keychain "Name"
4189 label
= CFBundleCopyLocalizedString(bundle
,
4190 CFSTR("KEYCHAIN_EAPOL_PASSWORD"),
4191 CFSTR("802.1X Password"),
4193 // "Internet Connect" --> keychain "Kind"
4194 description
= CFBundleCopyLocalizedString(bundle
,
4195 CFSTR("KEYCHAIN_INTERNET_CONNECT"),
4196 CFSTR("Internet Connect"),
4201 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
4203 (label
!= NULL
) ? label
: CFSTR("802.1X Password"),
4204 (description
!= NULL
) ? description
: CFSTR("Internet Connect"),
4209 CFMutableDictionaryRef newConfig
= NULL
;
4211 if (config
!= NULL
) {
4212 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
4214 newConfig
= CFDictionaryCreateMutable(NULL
,
4216 &kCFTypeDictionaryKeyCallBacks
,
4217 &kCFTypeDictionaryValueCallBacks
);
4219 CFDictionarySetValue(newConfig
,
4220 kEAPClientPropUserPasswordKeychainItemID
,
4222 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
4225 CFRelease(newConfig
);
4228 CFRelease(unique_id
);
4229 if (label
!= NULL
) CFRelease(label
);
4230 if (description
!= NULL
) CFRelease(description
);
4235 _SCErrorSet(kSCStatusInvalidArgument
);
4244 #pragma mark SCNetworkInterface [InterfaceNamer] SPIs
4247 SCNetworkInterfaceRef
4248 _SCNetworkInterfaceCreateWithIONetworkInterfaceObject(io_object_t if_obj
)
4250 SCNetworkInterfaceRef interface
;
4252 /* initialize runtime */
4253 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4255 interface
= createInterface(if_obj
, processNetworkInterface
);
4261 _SCNetworkInterfaceGetHardwareAddress(SCNetworkInterfaceRef interface
)
4263 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4265 return interfacePrivate
->address
;
4270 _SCNetworkInterfaceGetIOInterfaceType(SCNetworkInterfaceRef interface
)
4272 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4274 return interfacePrivate
->type
;
4279 _SCNetworkInterfaceGetIOInterfaceUnit(SCNetworkInterfaceRef interface
)
4281 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4283 return interfacePrivate
->unit
;
4288 _SCNetworkInterfaceGetIOPath(SCNetworkInterfaceRef interface
)
4290 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4292 return interfacePrivate
->path
;
4297 _SCNetworkInterfaceIsBuiltin(SCNetworkInterfaceRef interface
)
4299 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4301 return interfacePrivate
->builtin
;
4306 #pragma mark SCNetworkInterface SPIs
4309 _SCNetworkInterfaceIsModemV92(SCNetworkInterfaceRef interface
)
4311 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4313 return interfacePrivate
->modemIsV92
;
4318 #pragma mark SCNetworkInterface [internal] SPIs
4322 SCNetworkInterfacePrivateRef
4323 __SCNetworkInterfaceCreateCopy(CFAllocatorRef allocator
,
4324 SCNetworkInterfaceRef interface
,
4325 SCPreferencesRef prefs
,
4326 CFStringRef serviceID
)
4328 SCNetworkInterfacePrivateRef oldPrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4329 SCNetworkInterfacePrivateRef newPrivate
;
4331 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
4332 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4334 newPrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, prefs
, serviceID
, NULL
);
4335 newPrivate
->interface_type
= oldPrivate
->interface_type
;
4336 if (oldPrivate
->interface
!= NULL
) {
4337 newPrivate
->interface
= (SCNetworkInterfaceRef
)__SCNetworkInterfaceCreateCopy(NULL
, // allocator
4338 oldPrivate
->interface
, // interface
4339 prefs
, // [new] prefs
4340 serviceID
); // [new] serviceID
4342 if (oldPrivate
->name
!= NULL
) {
4343 newPrivate
->name
= CFRetain(oldPrivate
->name
);
4345 if (oldPrivate
->localized_name
!= NULL
) {
4346 newPrivate
->localized_name
= CFRetain(oldPrivate
->localized_name
);
4348 newPrivate
->localized_key
= oldPrivate
->localized_key
;
4349 if (oldPrivate
->localized_arg1
!= NULL
) {
4350 newPrivate
->localized_arg1
= CFRetain(oldPrivate
->localized_arg1
);
4352 if (oldPrivate
->localized_arg2
!= NULL
) {
4353 newPrivate
->localized_arg2
= CFRetain(oldPrivate
->localized_arg2
);
4355 if (oldPrivate
->unsaved
!= NULL
) {
4356 newPrivate
->unsaved
= CFDictionaryCreateMutableCopy(NULL
, 0, oldPrivate
->unsaved
);
4358 if (oldPrivate
->entity_device
!= NULL
) {
4359 newPrivate
->entity_device
= CFRetain(oldPrivate
->entity_device
);
4361 newPrivate
->entity_type
= oldPrivate
->entity_type
;
4362 newPrivate
->entity_subtype
= oldPrivate
->entity_subtype
;
4363 if (oldPrivate
->supported_interface_types
!= NULL
) {
4364 newPrivate
->supported_interface_types
= CFArrayCreateMutableCopy(NULL
, 0, oldPrivate
->supported_interface_types
);
4366 if (oldPrivate
->supported_protocol_types
!= NULL
) {
4367 newPrivate
->supported_protocol_types
= CFArrayCreateMutableCopy(NULL
, 0, oldPrivate
->supported_protocol_types
);
4369 if (oldPrivate
->address
!= NULL
) {
4370 newPrivate
->address
= CFRetain(oldPrivate
->address
);
4372 newPrivate
->builtin
= oldPrivate
->builtin
;
4373 if (oldPrivate
->location
!= NULL
) {
4374 newPrivate
->location
= CFRetain(oldPrivate
->location
);
4376 if (oldPrivate
->path
!= NULL
) {
4377 newPrivate
->path
= CFRetain(oldPrivate
->path
);
4379 if (oldPrivate
->overrides
!= NULL
) {
4380 newPrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, oldPrivate
->overrides
);
4382 newPrivate
->modemIsV92
= oldPrivate
->modemIsV92
;
4383 newPrivate
->supportsBond
= oldPrivate
->supportsBond
;
4384 newPrivate
->supportsVLAN
= oldPrivate
->supportsVLAN
;
4385 if (oldPrivate
->type
!= NULL
) {
4386 newPrivate
->type
= CFRetain(oldPrivate
->type
);
4388 if (oldPrivate
->unit
!= NULL
) {
4389 newPrivate
->unit
= CFRetain(oldPrivate
->unit
);
4391 newPrivate
->sort_order
= oldPrivate
->sort_order
;
4392 if (oldPrivate
->bond
.interfaces
!= NULL
) {
4393 newPrivate
->bond
.interfaces
= CFRetain(oldPrivate
->bond
.interfaces
);
4395 if (oldPrivate
->bond
.mode
!= NULL
) {
4396 newPrivate
->bond
.mode
= CFRetain(oldPrivate
->bond
.mode
);
4398 if (oldPrivate
->bond
.options
!= NULL
) {
4399 newPrivate
->bond
.options
= CFRetain(oldPrivate
->bond
.options
);
4401 if (oldPrivate
->vlan
.interface
!= NULL
) {
4402 newPrivate
->vlan
.interface
= CFRetain(oldPrivate
->vlan
.interface
);
4404 if (oldPrivate
->vlan
.tag
!= NULL
) {
4405 newPrivate
->vlan
.tag
= CFRetain(oldPrivate
->vlan
.tag
);
4407 if (oldPrivate
->vlan
.options
!= NULL
) {
4408 newPrivate
->vlan
.options
= CFRetain(oldPrivate
->vlan
.options
);
4417 __SCNetworkInterfaceCopyDeepConfiguration(SCNetworkInterfaceRef interface
)
4419 CFMutableArrayRef configs
;
4421 configs
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4423 while (interface
!= NULL
) {
4424 CFStringRef defaultType
;
4425 CFMutableDictionaryRef interfaceConfiguration
;
4427 interfaceConfiguration
= CFDictionaryCreateMutable(NULL
,
4429 &kCFTypeDictionaryKeyCallBacks
,
4430 &kCFTypeDictionaryValueCallBacks
);
4432 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
4433 if (defaultType
!= NULL
) {
4434 CFDictionaryRef config
;
4435 CFArrayRef extendedTypes
;
4437 config
= __SCNetworkInterfaceGetConfiguration(interface
, defaultType
);
4438 if (config
== NULL
) {
4439 config
= (CFDictionaryRef
)kCFNull
;
4441 CFDictionarySetValue(interfaceConfiguration
, defaultType
, config
);
4443 extendedTypes
= extendedConfigurationTypes(interface
);
4444 if (extendedTypes
!= NULL
) {
4448 n
= CFArrayGetCount(extendedTypes
);
4449 for (i
= 0; i
< n
; i
++) {
4450 CFStringRef extendedType
;
4452 extendedType
= CFArrayGetValueAtIndex(extendedTypes
, i
);
4453 config
= __SCNetworkInterfaceGetConfiguration(interface
, extendedType
);
4454 if (config
== NULL
) {
4455 config
= (CFDictionaryRef
)kCFNull
;
4457 CFDictionarySetValue(interfaceConfiguration
, extendedType
, config
);
4460 CFRelease(extendedTypes
);
4464 CFArrayAppendValue(configs
, interfaceConfiguration
);
4465 CFRelease(interfaceConfiguration
);
4467 interface
= SCNetworkInterfaceGetInterface(interface
);
4476 __SCNetworkInterfaceSetDeepConfiguration(SCNetworkInterfaceRef interface
, CFArrayRef configs
)
4480 for (i
= 0; interface
!= NULL
; i
++) {
4481 CFStringRef defaultType
;
4482 CFDictionaryRef interfaceConfiguration
;
4484 interfaceConfiguration
= (configs
!= NULL
) ? CFArrayGetValueAtIndex(configs
, i
) : NULL
;
4486 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
4487 if (defaultType
!= NULL
) {
4488 CFDictionaryRef config
;
4489 CFArrayRef extendedTypes
;
4491 config
= (interfaceConfiguration
!= NULL
) ? CFDictionaryGetValue(interfaceConfiguration
, defaultType
)
4493 if (config
== (CFDictionaryRef
)kCFNull
) {
4496 if (!__SCNetworkInterfaceSetConfiguration(interface
, defaultType
, config
, TRUE
)) {
4497 SCLog(TRUE
, LOG_DEBUG
,
4498 CFSTR("__SCNetworkInterfaceSetDeepConfiguration __SCNetworkInterfaceSetConfiguration() failed, interface=%@, type=%@"),
4503 extendedTypes
= extendedConfigurationTypes(interface
);
4504 if (extendedTypes
!= NULL
) {
4508 n
= CFArrayGetCount(extendedTypes
);
4509 for (j
= 0; j
< n
; j
++) {
4510 CFStringRef extendedType
;
4512 extendedType
= CFArrayGetValueAtIndex(extendedTypes
, j
);
4513 config
= (interfaceConfiguration
!= NULL
) ? CFDictionaryGetValue(interfaceConfiguration
, extendedType
)
4515 if (config
== (CFDictionaryRef
)kCFNull
) {
4518 if (!__SCNetworkInterfaceSetConfiguration(interface
, extendedType
, config
, TRUE
)) {
4519 SCLog(TRUE
, LOG_DEBUG
,
4520 CFSTR("__SCNetworkInterfaceSetDeepConfiguration __SCNetworkInterfaceSetConfiguration() failed, interface=%@, type=%@"),
4526 CFRelease(extendedTypes
);
4530 interface
= SCNetworkInterfaceGetInterface(interface
);