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
;
1345 } else if (CFEqual(provider
, CFSTR("IOUSBDevice"))) {
1348 // check if a "Product Name" has been provided
1349 val
= IORegistryEntrySearchCFProperty(interface
,
1351 CFSTR(kIOPropertyProductNameKey
),
1353 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1355 CFStringRef productName
;
1357 productName
= IOCopyCFStringValue(val
);
1360 if (productName
!= NULL
) {
1361 if (CFStringGetLength(productName
) > 0) {
1362 // if we have a [somewhat reasonable?] product name
1363 if (interfacePrivate
->name
!= NULL
) {
1364 CFRelease(interfacePrivate
->name
);
1366 interfacePrivate
->name
= CFRetain(productName
);
1367 if (interfacePrivate
->localized_name
!= NULL
) {
1368 CFRelease(interfacePrivate
->localized_name
);
1370 interfacePrivate
->localized_name
= copy_interface_string(bundle
, productName
, TRUE
);
1373 CFRelease(productName
);
1376 interfacePrivate
->localized_key
= CFSTR("usb-ether");
1377 interfacePrivate
->localized_arg1
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOBSDNameKey
));
1380 CFRelease(provider
);
1383 if (interfacePrivate
->localized_key
== NULL
) {
1384 // if no provider, not a PCI device, or no slot information
1385 interfacePrivate
->localized_key
= CFSTR("generic-ether");
1386 interfacePrivate
->localized_arg1
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOBSDNameKey
));
1393 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeFireWire
;
1396 interfacePrivate
->entity_type
= kSCEntNetFireWire
;
1399 interfacePrivate
->builtin
= isBuiltin(interface
);
1402 interfacePrivate
->sort_order
= kSortFireWire
;
1405 if (interfacePrivate
->builtin
) {
1406 interfacePrivate
->localized_key
= CFSTR("firewire");
1408 CFStringRef slot_name
;
1410 slot_name
= pci_slot(interface
, NULL
);
1411 if (slot_name
!= NULL
) {
1412 interfacePrivate
->localized_key
= CFSTR("pci-firewire");
1413 interfacePrivate
->localized_arg1
= slot_name
;
1419 SCLog(TRUE
, LOG_DEBUG
, CFSTR("processNetworkInterface() failed, unknown interface type = %d"), ift
);
1424 interfacePrivate
->entity_device
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOBSDNameKey
));
1426 // Hardware (MAC) address
1427 data
= CFDictionaryGetValue(controller_dict
, CFSTR(kIOMACAddress
));
1428 if (isA_CFData(data
)) {
1429 interfacePrivate
->address
= CFRetain(data
);
1433 num
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceUnit
));
1434 if (isA_CFNumber(num
) &&
1435 CFNumberGetValue(num
, kCFNumberIntType
, & iVal
)) {
1436 interfacePrivate
->unit
= CFRetain(num
);
1444 set_connection_script(SCNetworkInterfacePrivateRef interfacePrivate
, CFStringRef script
)
1446 CFDictionaryRef dict
;
1447 CFMutableDictionaryRef newDict
;
1449 if (interfacePrivate
->overrides
== NULL
) {
1450 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
1452 &kCFTypeDictionaryKeyCallBacks
,
1453 &kCFTypeDictionaryValueCallBacks
);
1456 dict
= CFDictionaryGetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
1458 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
1460 newDict
= CFDictionaryCreateMutable(NULL
,
1462 &kCFTypeDictionaryKeyCallBacks
,
1463 &kCFTypeDictionaryValueCallBacks
);
1465 if (script
!= NULL
) {
1466 CFDictionarySetValue(newDict
, kSCPropNetModemConnectionScript
, script
);
1468 CFDictionaryRemoveValue(newDict
, kSCPropNetModemConnectionScript
);
1470 if (CFDictionaryGetCount(newDict
) > 0) {
1471 CFDictionarySetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
, newDict
);
1473 CFDictionaryRemoveValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
1477 if (CFDictionaryGetCount(interfacePrivate
->overrides
) == 0) {
1478 CFRelease(interfacePrivate
->overrides
);
1479 interfacePrivate
->overrides
= NULL
;
1486 is_valid_connection_script(CFStringRef script
)
1488 char ccl
[MAXPATHLEN
];
1489 char path
[MAXPATHLEN
];
1490 NSSearchPathEnumerationState state
;
1492 (void) _SC_cfstring_to_cstring(script
,
1495 kCFStringEncodingUTF8
);
1497 state
= NSStartSearchPathEnumeration(NSLibraryDirectory
,
1498 NSLocalDomainMask
|NSSystemDomainMask
);
1499 while ((state
= NSGetNextSearchPathEnumeration(state
, path
))) {
1501 struct stat statBuf
;
1503 if (ccl
[0] == '/') {
1504 path
[0] = '\0'; // if modemCCL is a full path
1506 strlcat(path
, "/Modem Scripts/", sizeof(path
));
1508 strlcat(path
, ccl
, sizeof(path
));
1510 if (stat(path
, &statBuf
) != 0) {
1511 if (errno
== ENOENT
) {
1515 SCLog(TRUE
, LOG_DEBUG
,
1516 CFSTR("processSerialInterface stat() failed: %s"),
1520 if (S_ISREG(statBuf
.st_mode
)) {
1521 // if we have a valid CCL script
1525 #define BUNDLE_EXT ".ccl"
1526 #define BUNDLE_EXT_LEN sizeof(BUNDLE_EXT) - 1
1531 if ((n
<= BUNDLE_EXT_LEN
) ||
1532 (strstr(&path
[n
- BUNDLE_EXT_LEN
], BUNDLE_EXT
) == NULL
)) {
1533 strlcat(path
, BUNDLE_EXT
, sizeof(path
));
1534 if (stat(path
, &statBuf
) != 0) {
1535 if (errno
== ENOENT
) {
1539 SCLog(TRUE
, LOG_DEBUG
,
1540 CFSTR("processSerialInterface stat() failed: %s"),
1545 if (S_ISDIR(statBuf
.st_mode
)) {
1546 // if we have a valid CCL bundle
1556 processSerialInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1557 io_registry_entry_t interface
,
1558 CFDictionaryRef interface_dict
,
1559 io_registry_entry_t controller
,
1560 CFDictionaryRef controller_dict
,
1561 io_registry_entry_t bus
,
1562 CFDictionaryRef bus_dict
)
1565 Boolean isModem
= FALSE
;
1566 CFStringRef modemCCL
= NULL
;
1571 val
= IORegistryEntrySearchCFProperty(interface
,
1573 CFSTR("HiddenPort"),
1575 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1578 return FALSE
; // if this interface should not be exposed
1582 str
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOTTYBaseNameKey
));
1590 * Exclude ports named "irda" because otherwise the IrDA ports on the
1591 * original iMac (rev's A through D) show up as serial ports. Given
1592 * that only the rev A actually had an IrDA port, and Mac OS X doesn't
1593 * even support it, these ports definitely shouldn't be listed.
1595 if (CFStringCompare(str
,
1597 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
1601 if (IOStringValueHasPrefix(str
, CFSTR("bluetooth"))) {
1603 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBluetooth
;
1604 interfacePrivate
->sort_order
= kSortBluetooth
;
1605 } else if (IOStringValueHasPrefix(str
, CFSTR("irda-ircomm"))) {
1607 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIrDA
;
1608 interfacePrivate
->sort_order
= kSortIrDA
;
1609 } else if (IOStringValueHasPrefix(str
, CFSTR("wwan"))) {
1611 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeWWAN
;
1612 interfacePrivate
->sort_order
= kSortWWAN
;
1615 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeModem
;
1616 interfacePrivate
->sort_order
= kSortModem
;
1619 val
= IORegistryEntrySearchCFProperty(interface
,
1621 CFSTR(kIODeviceSupportsHoldKey
),
1623 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1627 if (isA_CFNumber(val
) &&
1628 CFNumberGetValue(val
, kCFNumberSInt32Type
, &v92
)) {
1629 interfacePrivate
->modemIsV92
= (v92
== 1);
1636 interfacePrivate
->entity_type
= kSCEntNetModem
;
1638 // Entity (Hardware)
1639 ift
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOSerialBSDTypeKey
));
1640 if (!isA_CFString(ift
)) {
1644 if (CFEqual(ift
, CFSTR(kIOSerialBSDModemType
))) {
1648 if (CFEqual(str
, CFSTR("modem"))) {
1649 interfacePrivate
->builtin
= TRUE
;
1650 interfacePrivate
->sort_order
= kSortInternalModem
;
1651 } else if (CFEqual(str
, CFSTR("usbmodem"))) {
1652 interfacePrivate
->sort_order
= kSortUSBModem
;
1654 } else if (CFEqual(ift
, CFSTR(kIOSerialBSDRS232Type
))) {
1656 interfacePrivate
->sort_order
= kSortSerialPort
;
1662 interfacePrivate
->entity_device
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOTTYDeviceKey
));
1664 // configuration template overrides
1665 val
= IORegistryEntrySearchCFProperty(interface
,
1667 CFSTR("DevicePPPOverrides"),
1669 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1671 if (isA_CFDictionary(val
)) {
1672 if (interfacePrivate
->overrides
== NULL
) {
1673 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
1675 &kCFTypeDictionaryKeyCallBacks
,
1676 &kCFTypeDictionaryValueCallBacks
);
1678 CFDictionarySetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypePPP
, val
);
1683 val
= IORegistryEntrySearchCFProperty(interface
,
1685 CFSTR("DeviceModemOverrides"),
1687 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1689 if (isA_CFDictionary(val
)) {
1690 if (interfacePrivate
->overrides
== NULL
) {
1691 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
1693 &kCFTypeDictionaryKeyCallBacks
,
1694 &kCFTypeDictionaryValueCallBacks
);
1696 CFDictionarySetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
, val
);
1698 modemCCL
= CFDictionaryGetValue(val
, kSCPropNetModemConnectionScript
);
1699 modemCCL
= isA_CFString(modemCCL
);
1705 if (modemCCL
== NULL
) {
1706 val
= IORegistryEntrySearchCFProperty(interface
,
1710 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1712 modemCCL
= IOCopyCFStringValue(val
);
1713 if (modemCCL
!= NULL
) {
1714 set_connection_script(interfacePrivate
, modemCCL
);
1715 CFRelease(modemCCL
);
1723 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIrDA
)) {
1724 interfacePrivate
->localized_key
= CFSTR("irda");
1725 } else if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBluetooth
)) {
1726 interfacePrivate
->localized_key
= CFSTR("bluetooth");
1728 CFStringRef localized
= NULL
;
1729 CFStringRef name
= NULL
;
1730 CFMutableStringRef port
;
1732 port
= CFStringCreateMutableCopy(NULL
, 0, str
);
1733 CFStringLowercase(port
, NULL
);
1736 CFStringAppend(port
, CFSTR("-port"));
1739 // set non-localized name
1740 if (bundle
!= NULL
) {
1741 name
= copy_interface_string(bundle
, port
, FALSE
);
1744 if (!CFEqual(port
, name
)) {
1745 // if [English] localization available
1746 interfacePrivate
->name
= name
;
1748 // if no [English] localization available, use TTY base name
1750 interfacePrivate
->name
= CFStringCreateCopy(NULL
, str
);
1753 interfacePrivate
->name
= CFStringCreateCopy(NULL
, str
);
1756 // set localized name
1757 if (bundle
!= NULL
) {
1758 localized
= copy_interface_string(bundle
, port
, TRUE
);
1760 if (localized
!= NULL
) {
1761 if (!CFEqual(port
, localized
)) {
1762 // if localization available
1763 interfacePrivate
->localized_name
= localized
;
1765 // if no localization available, use TTY base name
1766 CFRelease(localized
);
1767 interfacePrivate
->localized_name
= CFStringCreateCopy(NULL
, str
);
1770 interfacePrivate
->localized_name
= CFStringCreateCopy(NULL
, str
);
1773 if (!isModem
|| !CFEqual(str
, CFSTR("modem"))) {
1774 CFStringRef productName
;
1776 // check if a "Product Name" has been provided
1777 val
= IORegistryEntrySearchCFProperty(interface
,
1779 CFSTR(kIOPropertyProductNameKey
),
1781 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1783 productName
= IOCopyCFStringValue(val
);
1786 if (productName
!= NULL
) {
1787 if (CFStringGetLength(productName
) > 0) {
1788 // if we have a [somewhat reasonable?] product name
1789 if (interfacePrivate
->name
!= NULL
) {
1790 CFRelease(interfacePrivate
->name
);
1792 interfacePrivate
->name
= CFRetain(productName
);
1793 if (interfacePrivate
->localized_name
!= NULL
) {
1794 CFRelease(interfacePrivate
->localized_name
);
1796 interfacePrivate
->localized_name
= copy_interface_string(bundle
, productName
, TRUE
);
1798 // if not provided, also check if the product name
1799 // matches a CCL script
1800 if ((modemCCL
== NULL
) &&
1801 is_valid_connection_script(productName
)) {
1802 set_connection_script(interfacePrivate
, productName
);
1803 modemCCL
= productName
;
1807 CFRelease(productName
);
1819 static SCNetworkInterfaceRef
1820 createInterface(io_registry_entry_t interface
, processInterface func
)
1822 io_registry_entry_t bus
= MACH_PORT_NULL
;
1823 CFMutableDictionaryRef bus_dict
= NULL
;
1824 io_registry_entry_t controller
= MACH_PORT_NULL
;
1825 CFMutableDictionaryRef controller_dict
= NULL
;
1826 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
1827 CFMutableDictionaryRef interface_dict
= NULL
;
1831 kr
= IORegistryEntryGetPath(interface
, kIOServicePlane
, path
);
1832 if (kr
!= kIOReturnSuccess
) {
1833 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryGetPath() failed, kr = 0x%x"), kr
);
1837 kr
= IORegistryEntryCreateCFProperties(interface
, &interface_dict
, NULL
, kNilOptions
);
1838 if (kr
!= kIOReturnSuccess
) {
1839 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryCreateCFProperties() failed, kr = 0x%x"), kr
);
1843 /* get the controller node */
1844 kr
= IORegistryEntryGetParentEntry(interface
, kIOServicePlane
, &controller
);
1845 if (kr
!= KERN_SUCCESS
) {
1846 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr
);
1850 /* get the dictionary associated with the node */
1851 kr
= IORegistryEntryCreateCFProperties(controller
, &controller_dict
, NULL
, kNilOptions
);
1852 if (kr
!= KERN_SUCCESS
) {
1853 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryCreateCFProperties() failed, kr = 0x%x"), kr
);
1857 /* get the bus node */
1858 kr
= IORegistryEntryGetParentEntry(controller
, kIOServicePlane
, &bus
);
1859 if (kr
!= KERN_SUCCESS
) {
1860 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr
);
1864 /* get the dictionary associated with the node */
1865 kr
= IORegistryEntryCreateCFProperties(bus
, &bus_dict
, NULL
, kNilOptions
);
1866 if (kr
!= KERN_SUCCESS
) {
1867 SCLog(TRUE
, LOG_DEBUG
, CFSTR("createInterface IORegistryEntryCreateCFProperties() failed, kr = 0x%x"), kr
);
1871 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
, path
);
1873 if (!(*func
)(interfacePrivate
, interface
, interface_dict
, controller
, controller_dict
, bus
, bus_dict
)) {
1874 CFRelease(interfacePrivate
);
1875 interfacePrivate
= NULL
;
1880 if (interface_dict
!= NULL
) CFRelease(interface_dict
);
1882 if (controller
!= MACH_PORT_NULL
) IOObjectRelease(controller
);
1883 if (controller_dict
!= NULL
) CFRelease(controller_dict
);
1885 if (bus
!= MACH_PORT_NULL
) IOObjectRelease(bus
);
1886 if (bus_dict
!= NULL
) CFRelease(bus_dict
);
1888 return (SCNetworkInterfaceRef
)interfacePrivate
;
1893 findMatchingInterfaces(CFDictionaryRef matching
, processInterface func
)
1895 CFMutableArrayRef interfaces
;
1896 io_registry_entry_t interface
;
1898 io_iterator_t iterator
= MACH_PORT_NULL
;
1900 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &iterator
);
1901 if (kr
!= kIOReturnSuccess
) {
1902 SCLog(TRUE
, LOG_DEBUG
, CFSTR("findMatchingInterfaces IOServiceGetMatchingServices() failed, kr = 0x%x"), kr
);
1906 interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1908 while ((interface
= IOIteratorNext(iterator
)) != MACH_PORT_NULL
) {
1909 SCNetworkInterfaceRef match
;
1911 match
= createInterface(interface
, func
);
1912 if (match
!= NULL
) {
1913 CFArrayAppendValue(interfaces
, match
);
1917 IOObjectRelease(interface
);
1920 IOObjectRelease(iterator
);
1927 #pragma mark helper functions
1931 findConfiguration(CFStringRef interface_type
)
1935 for (i
= 0; i
< sizeof(configurations
)/sizeof(configurations
[0]); i
++) {
1936 if (CFEqual(interface_type
, *configurations
[i
].interface_type
)) {
1947 __SCNetworkInterfaceGetDefaultConfigurationType(SCNetworkInterfaceRef interface
)
1949 CFIndex interfaceIndex
;
1950 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
1952 if (interfacePrivate
->serviceID
== NULL
) {
1953 // if not associated with a service (yet)
1954 _SCErrorSet(kSCStatusInvalidArgument
);
1958 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
1959 if (interfaceIndex
== kCFNotFound
) {
1960 // unknown interface type, use per-service configuration preferences
1961 return interfacePrivate
->interface_type
; // entity
1964 if (configurations
[interfaceIndex
].entity_hardware
!= NULL
) {
1965 // if configuration information can be associated with this interface type
1966 return *configurations
[interfaceIndex
].entity_hardware
;
1969 _SCErrorSet(kSCStatusInvalidArgument
);
1976 __SCNetworkInterfaceIsValidExtendedConfigurationType(SCNetworkInterfaceRef interface
,
1977 CFStringRef extendedType
,
1978 Boolean requirePerInterface
)
1980 CFStringRef defaultType
;
1981 CFIndex extendedIndex
;
1982 CFIndex interfaceIndex
;
1983 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
1986 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
1987 if (defaultType
== NULL
) {
1991 if (CFEqual(extendedType
, defaultType
)) {
1992 // extended and default configuration types cannot conflict
1996 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
1997 if (interfaceIndex
== kCFNotFound
) {
1998 // configuration information for unknown interface type's
1999 // are stored along with the service and we don't allow
2000 // per-service extended configurations
2004 // It turns out that, for PPP interfaces, we want to be able to store
2005 // some extended interface configuration (e.g. IPSec [for L2TP]). For
2006 // now, I'm commenting out the following test.
2008 // if (requirePerInterface && !configurations[interfaceIndex].per_interface_config) {
2009 // // we don't allow per-service extended configurations
2013 extendedIndex
= findConfiguration(extendedType
);
2014 if (extendedIndex
!= kCFNotFound
) {
2015 // extended type cannot match a known interface type
2021 * Do we match specific/known extended configuration types (e.g. EAPOL)
2022 * and ensure that any non-standard extended configuration types be of
2023 * the form com.myCompany.myType?
2032 _SCErrorSet(kSCStatusInvalidArgument
);
2039 CFStringRef defaultType
;
2040 CFMutableArrayRef types
;
2041 } extendedConfiguration
, *extendedConfigurationRef
;
2045 __addExtendedConfigurationType(const void *key
, const void *value
, void *context
)
2047 CFStringRef extendedType
= (CFStringRef
)key
;
2048 extendedConfigurationRef myContextRef
= (extendedConfigurationRef
)context
;
2050 if (CFEqual(extendedType
, myContextRef
->defaultType
)) {
2051 // do not include the default configuration type
2055 if (CFArrayContainsValue(myContextRef
->types
,
2056 CFRangeMake(0, CFArrayGetCount(myContextRef
->types
)),
2058 // if extendedType already has already been added
2062 CFArrayAppendValue(myContextRef
->types
, extendedType
);
2069 extendedConfigurationTypes(SCNetworkInterfaceRef interface
)
2072 CFIndex interfaceIndex
;
2073 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2074 extendedConfiguration myContext
;
2075 SCNetworkServiceRef service
;
2079 myContext
.defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
2080 if (myContext
.defaultType
== NULL
) {
2081 myContext
.types
= NULL
;
2085 myContext
.types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2087 if (interfacePrivate
->serviceID
== NULL
) {
2088 // if not associated with a service (yet)
2092 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2093 if (interfaceIndex
== kCFNotFound
) {
2094 // we don't allow per-service extended configurations
2098 if (!configurations
[interfaceIndex
].per_interface_config
) {
2099 // known interface type but we still don't allow
2100 // per-service extended configurations
2104 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
2105 interfacePrivate
->prefs
,
2106 interfacePrivate
->serviceID
,
2109 sets
= SCNetworkSetCopyAll(interfacePrivate
->prefs
);
2110 n
= (sets
!= NULL
) ? CFArrayGetCount(sets
) : 0;
2112 for (i
= 0; i
< n
; i
++) {
2113 CFDictionaryRef configs
;
2116 CFArrayRef services
;
2117 SCNetworkSetRef set
;
2119 set
= CFArrayGetValueAtIndex(sets
, i
);
2120 services
= SCNetworkSetCopyServices(set
);
2121 found
= CFArrayContainsValue(services
,
2122 CFRangeMake(0, CFArrayGetCount(services
)),
2124 CFRelease(services
);
2130 // add stored extended configuration types
2131 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
2132 SCNetworkSetGetSetID(set
), // set
2133 interfacePrivate
->entity_device
, // service
2135 configs
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
2137 if (isA_CFDictionary(configs
)) {
2138 CFDictionaryApplyFunction(configs
,
2139 __addExtendedConfigurationType
,
2143 // add not-yet-stored extended configuration types
2144 if (interfacePrivate
->unsaved
!= NULL
) {
2145 CFDictionaryApplyFunction(interfacePrivate
->unsaved
,
2146 __addExtendedConfigurationType
,
2154 if (sets
!= NULL
) CFRelease(sets
);
2158 return myContext
.types
;
2163 copyConfigurationPaths(SCNetworkInterfacePrivateRef interfacePrivate
,
2164 CFStringRef extendedType
)
2166 CFMutableArrayRef array
;
2168 CFIndex interfaceIndex
;
2171 SCNetworkServiceRef service
;
2174 array
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2176 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2177 if (interfaceIndex
== kCFNotFound
) {
2178 // unknown interface type, use per-service configuration preferences
2179 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
2180 interfacePrivate
->serviceID
, // service
2181 extendedType
); // entity
2182 CFArrayAppendValue(array
, path
);
2187 if (!configurations
[interfaceIndex
].per_interface_config
) {
2188 // known interface type, per-service configuration preferences
2189 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
2190 interfacePrivate
->serviceID
, // service
2191 extendedType
); // entity
2192 CFArrayAppendValue(array
, path
);
2197 // known interface type, per-interface configuration preferences
2199 // 1. look for all sets which contain the associated service
2200 // 2. add a per-set path for the interface configuration for
2203 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
2204 interfacePrivate
->prefs
,
2205 interfacePrivate
->serviceID
,
2206 (SCNetworkInterfaceRef
)interfacePrivate
);
2208 sets
= SCNetworkSetCopyAll(interfacePrivate
->prefs
);
2209 n
= (sets
!= NULL
) ? CFArrayGetCount(sets
) : 0;
2211 for (i
= 0; i
< n
; i
++) {
2212 CFArrayRef services
;
2213 SCNetworkSetRef set
;
2215 set
= CFArrayGetValueAtIndex(sets
, i
);
2216 services
= SCNetworkSetCopyServices(set
);
2217 if (CFArrayContainsValue(services
,
2218 CFRangeMake(0, CFArrayGetCount(services
)),
2220 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
2221 SCNetworkSetGetSetID(set
), // set
2222 interfacePrivate
->entity_device
, // service
2223 extendedType
); // entity
2224 CFArrayAppendValue(array
, path
);
2227 CFRelease(services
);
2230 if (CFArrayGetCount(array
) == 0) {
2236 if (sets
!= NULL
) CFRelease(sets
);
2242 #pragma mark SCNetworkInterface <--> preferences entity
2247 __SCNetworkInterfaceCopyInterfaceEntity(SCNetworkInterfaceRef interface
)
2249 CFMutableDictionaryRef entity
;
2250 CFIndex interfaceIndex
;
2251 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2253 entity
= CFDictionaryCreateMutable(NULL
,
2255 &kCFTypeDictionaryKeyCallBacks
,
2256 &kCFTypeDictionaryValueCallBacks
);
2257 if (interfacePrivate
->entity_type
!= NULL
) {
2258 CFDictionarySetValue(entity
,
2259 kSCPropNetInterfaceType
,
2260 interfacePrivate
->entity_type
);
2262 if (interfacePrivate
->entity_subtype
!= NULL
) {
2263 CFDictionarySetValue(entity
,
2264 kSCPropNetInterfaceSubType
,
2265 interfacePrivate
->entity_subtype
);
2267 if (interfacePrivate
->entity_device
!= NULL
) {
2268 CFDictionarySetValue(entity
,
2269 kSCPropNetInterfaceDeviceName
,
2270 interfacePrivate
->entity_device
);
2273 // match the "hardware" with the lowest layer
2275 SCNetworkInterfaceRef nextInterface
;
2277 nextInterface
= SCNetworkInterfaceGetInterface(interface
);
2278 if (nextInterface
== NULL
) {
2282 interface
= nextInterface
;
2284 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2286 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2287 if (interfaceIndex
!= kCFNotFound
) {
2288 if (configurations
[interfaceIndex
].entity_hardware
!= NULL
) {
2289 CFDictionarySetValue(entity
,
2290 kSCPropNetInterfaceHardware
,
2291 *configurations
[interfaceIndex
].entity_hardware
);
2294 CFDictionarySetValue(entity
,
2295 kSCPropNetInterfaceHardware
,
2296 interfacePrivate
->interface_type
);
2299 // add the localized display name (which will only be used when/if the
2300 // interface is removed from the system)
2301 CFDictionarySetValue(entity
,
2302 kSCPropUserDefinedName
,
2303 SCNetworkInterfaceGetLocalizedDisplayName(interface
));
2305 // note that this is a V.92 capable modem
2306 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeModem
) &&
2307 interfacePrivate
->modemIsV92
) {
2311 num
= CFNumberCreate(NULL
, kCFNumberIntType
, &one
);
2312 CFDictionarySetValue(entity
,
2313 kSCPropNetInterfaceSupportsModemOnHold
,
2322 static SCNetworkInterfaceRef
2323 findInterface(CFArrayRef interfaces
, CFStringRef match_if
)
2328 n
= CFArrayGetCount(interfaces
);
2329 for (i
= 0; i
< n
; i
++) {
2330 SCNetworkInterfaceRef interface
= CFArrayGetValueAtIndex(interfaces
, i
);
2331 CFStringRef interfaceName
;
2333 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
2334 if ((interfaceName
!= NULL
) && CFEqual(interfaceName
, match_if
)) {
2335 CFRetain(interface
);
2344 static SCNetworkInterfaceRef
2345 findBondInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
2348 SCNetworkInterfaceRef interface
= NULL
;
2350 if (prefs
== NULL
) {
2354 // check if the interface is an Ethernet Bond
2355 bonds
= SCBondInterfaceCopyAll(prefs
);
2356 if (bonds
!= NULL
) {
2357 interface
= findInterface(bonds
, ifDevice
);
2363 static SCNetworkInterfaceRef
2364 findVLANInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
2366 SCNetworkInterfaceRef interface
= NULL
;
2369 if (prefs
== NULL
) {
2373 // check if the interface is a VLAN
2374 vlans
= SCVLANInterfaceCopyAll(prefs
);
2375 if (vlans
!= NULL
) {
2376 interface
= findInterface(vlans
, ifDevice
);
2383 SCNetworkInterfaceRef
2384 _SCNetworkInterfaceCreateWithBSDName(CFAllocatorRef allocator
,
2385 CFStringRef bsdName
,
2388 CFMutableDictionaryRef entity
;
2389 SCNetworkInterfaceRef interface
;
2391 entity
= CFDictionaryCreateMutable(NULL
,
2393 &kCFTypeDictionaryKeyCallBacks
,
2394 &kCFTypeDictionaryValueCallBacks
);
2395 CFDictionarySetValue(entity
, kSCPropNetInterfaceDeviceName
, bsdName
);
2396 if ((flags
& kIncludeVLANInterfaces
) == 0) {
2397 CFDictionarySetValue(entity
, CFSTR("_NO_VLAN_INTERFACES_"), kCFBooleanTrue
);
2399 if ((flags
& kIncludeBondInterfaces
) == 0) {
2400 CFDictionarySetValue(entity
, CFSTR("_NO_BOND_INTERFACES_"), kCFBooleanTrue
);
2402 interface
= _SCNetworkInterfaceCreateWithEntity(NULL
, entity
, NULL
);
2409 SCNetworkInterfaceRef
2410 _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef allocator
,
2411 CFDictionaryRef interface_entity
,
2412 SCNetworkServiceRef service
)
2414 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
2415 CFStringRef ifDevice
;
2416 CFStringRef ifSubType
;
2418 CFArrayRef matching_interfaces
= NULL
;
2420 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
2421 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
2423 ifType
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceType
);
2424 if (ifType
== NULL
) {
2426 * The interface "Type" was not specified. We'll make an
2427 * assumption that this is an "Ethernet" interface. If a
2428 * real interface exists with the provided interface name
2429 * then the actual type will be set accordingly. If not, we'll
2430 * end up crafting an "Ethernet" SCNetworkInterface which
2431 * will keep the rest of the configuration APIs happy.
2433 ifType
= kSCValNetInterfaceTypeEthernet
;
2436 if (!isA_CFString(ifType
)) {
2440 ifSubType
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceSubType
);
2441 if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
2442 if (!isA_CFString(ifSubType
)) {
2447 ifDevice
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceDeviceName
);
2449 if (CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
) ||
2450 CFEqual(ifType
, kSCValNetInterfaceTypeFireWire
) ||
2451 (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) && CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPoE
))) {
2452 char bsdName
[IFNAMSIZ
+ 1];
2453 CFMutableDictionaryRef matching
;
2455 if (!isA_CFString(ifDevice
)) {
2459 if (_SC_cfstring_to_cstring(ifDevice
, bsdName
, sizeof(bsdName
), kCFStringEncodingASCII
) == NULL
) {
2463 matching
= IOBSDNameMatching(masterPort
, 0, bsdName
);
2464 if (matching
== NULL
) {
2468 // note: the "matching" dictionary will be consumed by the following
2469 matching_interfaces
= findMatchingInterfaces(matching
, processNetworkInterface
);
2471 } else if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
2472 if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPSerial
)) {
2473 CFDictionaryRef matching
;
2474 CFStringRef match_keys
[2];
2475 CFStringRef match_vals
[2];
2477 if (!isA_CFString(ifDevice
)) {
2481 match_keys
[0] = CFSTR(kIOProviderClassKey
);
2482 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
2484 match_keys
[1] = CFSTR(kIOTTYDeviceKey
);
2485 match_vals
[1] = ifDevice
;
2487 matching
= CFDictionaryCreate(NULL
,
2488 (const void **)match_keys
,
2489 (const void **)match_vals
,
2490 sizeof(match_keys
)/sizeof(match_keys
[0]),
2491 &kCFTypeDictionaryKeyCallBacks
,
2492 &kCFTypeDictionaryValueCallBacks
);
2494 // note: the "matching" dictionary will be consumed by the following
2495 matching_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
);
2497 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypeL2TP
)) {
2498 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
2499 kSCNetworkInterfaceTypeL2TP
);
2500 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPTP
)) {
2501 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
2502 kSCNetworkInterfaceTypePPTP
);
2504 // XXX do we allow non-Apple variants of PPP??? XXX
2505 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
2508 } else if (CFEqual(ifType
, kSCValNetInterfaceType6to4
)) {
2509 if (!isA_CFString(ifDevice
)) {
2513 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
2514 kSCNetworkInterfaceType6to4
);
2515 } else if ((CFStringFind(ifType
, CFSTR("."), 0).location
!= kCFNotFound
) && (ifDevice
== NULL
)) {
2516 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
2520 if (matching_interfaces
!= NULL
) {
2522 SCPreferencesRef prefs
;
2524 n
= CFArrayGetCount(matching_interfaces
);
2527 if (!CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
)) {
2530 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), NULL
);
2531 if (prefs
== NULL
) {
2534 if (!CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_VLAN_INTERFACES_"))) {
2535 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findVLANInterface(prefs
, ifDevice
);
2537 if ((interfacePrivate
== NULL
)
2538 && !CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_BOND_INTERFACES_"))) {
2539 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findBondInterface(prefs
, ifDevice
);
2544 interfacePrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, 0);
2545 CFRetain(interfacePrivate
);
2548 SCLog(TRUE
, LOG_DEBUG
, CFSTR("_SCNetworkInterfaceCreateWithEntity() failed, more than one interface matches %@"), ifDevice
);
2549 CFRelease(matching_interfaces
);
2550 _SCErrorSet(kSCStatusFailed
);
2553 CFRelease(matching_interfaces
);
2558 if (interfacePrivate
== NULL
) {
2560 * if device not present on this system
2562 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
, NULL
);
2563 interfacePrivate
->entity_type
= ifType
;
2564 interfacePrivate
->entity_subtype
= ifSubType
;
2565 interfacePrivate
->entity_device
= (ifDevice
!= NULL
) ? CFStringCreateCopy(NULL
, ifDevice
) : NULL
;
2567 if (CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
)) {
2568 CFStringRef entity_hardware
;
2570 entity_hardware
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceHardware
);
2571 if ((entity_hardware
!= NULL
) &&
2572 CFEqual(entity_hardware
, kSCEntNetAirPort
)) {
2573 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
2575 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
2577 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeFireWire
)) {
2578 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeFireWire
;
2579 } else if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
2580 if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPoE
)) {
2581 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
2582 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPSerial
)) {
2583 if (CFStringHasPrefix(ifDevice
, CFSTR("Bluetooth"))) {
2584 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBluetooth
;
2585 } else if (CFStringHasPrefix(ifDevice
, CFSTR("irda"))) {
2586 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIrDA
;
2587 } else if (CFStringHasPrefix(ifDevice
, CFSTR("wwan"))) {
2588 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeWWAN
;
2590 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeModem
;
2594 CFRelease(interfacePrivate
);
2595 interfacePrivate
= (SCNetworkInterfacePrivateRef
)kSCNetworkInterfaceIPv4
;
2596 CFRetain(interfacePrivate
);
2598 } else if (CFStringFind(ifType
, CFSTR("."), 0).location
!= kCFNotFound
) {
2599 // if vendor interface
2600 interfacePrivate
->interface_type
= ifType
;
2602 // if unknown interface
2603 CFRelease(interfacePrivate
);
2604 interfacePrivate
= NULL
;
2608 if ((interfacePrivate
!= NULL
) && (service
!= NULL
)) {
2609 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)service
;
2611 if (interfacePrivate
->prefs
!= NULL
)
2612 CFRelease(interfacePrivate
->prefs
);
2613 if (interfacePrivate
->serviceID
!= NULL
)
2614 CFRelease(interfacePrivate
->serviceID
);
2616 interfacePrivate
->prefs
= CFRetain(servicePrivate
->prefs
);
2617 interfacePrivate
->serviceID
= CFRetain(servicePrivate
->serviceID
);
2620 if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
2621 SCNetworkInterfaceRef parent
;
2623 parent
= SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef
)interfacePrivate
,
2624 kSCNetworkInterfaceTypePPP
);
2625 CFRelease(interfacePrivate
);
2626 interfacePrivate
= (SCNetworkInterfacePrivateRef
)parent
;
2629 return (SCNetworkInterfaceRef
)interfacePrivate
;
2634 #pragma mark SCNetworkInterface APIs
2639 __SCNetworkInterfaceCopyAll_IONetworkInterface(void)
2641 CFDictionaryRef matching
;
2642 CFArrayRef new_interfaces
;
2644 // get Ethernet, Firewire, and AirPort interfaces
2646 matching
= IOServiceMatching(kIONetworkInterfaceClass
);
2647 new_interfaces
= findMatchingInterfaces(matching
, processNetworkInterface
);
2649 return new_interfaces
;
2655 __SCNetworkInterfaceCopyAll_Modem()
2657 CFDictionaryRef matching
;
2658 CFStringRef match_keys
[2];
2659 CFStringRef match_vals
[2];
2660 CFArrayRef new_interfaces
;
2662 match_keys
[0] = CFSTR(kIOProviderClassKey
);
2663 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
2665 match_keys
[1] = CFSTR(kIOSerialBSDTypeKey
);
2666 match_vals
[1] = CFSTR(kIOSerialBSDModemType
);
2668 matching
= CFDictionaryCreate(NULL
,
2669 (const void **)match_keys
,
2670 (const void **)match_vals
,
2671 sizeof(match_keys
)/sizeof(match_keys
[0]),
2672 &kCFTypeDictionaryKeyCallBacks
,
2673 &kCFTypeDictionaryValueCallBacks
);
2674 new_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
);
2676 return new_interfaces
;
2682 __SCNetworkInterfaceCopyAll_RS232()
2684 CFDictionaryRef matching
;
2685 CFStringRef match_keys
[2];
2686 CFStringRef match_vals
[2];
2687 CFArrayRef new_interfaces
;
2689 match_keys
[0] = CFSTR(kIOProviderClassKey
);
2690 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
2692 match_keys
[1] = CFSTR(kIOSerialBSDTypeKey
);
2693 match_vals
[1] = CFSTR(kIOSerialBSDRS232Type
);
2695 matching
= CFDictionaryCreate(NULL
,
2696 (const void **)match_keys
,
2697 (const void **)match_vals
,
2698 sizeof(match_keys
)/sizeof(match_keys
[0]),
2699 &kCFTypeDictionaryKeyCallBacks
,
2700 &kCFTypeDictionaryValueCallBacks
);
2701 new_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
);
2703 return new_interfaces
;
2708 add_interfaces(CFMutableArrayRef all_interfaces
, CFArrayRef new_interfaces
)
2713 n
= CFArrayGetCount(new_interfaces
);
2714 for (i
= 0; i
< n
; i
++) {
2715 CFStringRef bsdName
;
2716 SCNetworkInterfaceRef interface
;
2718 interface
= CFArrayGetValueAtIndex(new_interfaces
, i
);
2719 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
2720 if (bsdName
!= NULL
) {
2721 CFArrayAppendValue(all_interfaces
, interface
);
2730 __waitForInterfaces()
2735 SCDynamicStoreRef store
;
2737 store
= SCDynamicStoreCreate(NULL
, CFSTR("SCNetworkInterfaceCopyAll"), NULL
, NULL
);
2738 if (store
== NULL
) {
2742 key
= SCDynamicStoreKeyCreate(NULL
, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin
);
2743 keys
= CFArrayCreate(NULL
, (const void **)&key
, 1, &kCFTypeArrayCallBacks
);
2744 ok
= SCDynamicStoreSetNotificationKeys(store
, keys
, NULL
);
2747 SCLog(TRUE
, LOG_ERR
,
2748 CFSTR("SCDynamicStoreSetNotificationKeys() failed: %s"), SCErrorString(SCError()));
2753 CFDictionaryRef dict
;
2754 Boolean quiet
= FALSE
;
2757 dict
= SCDynamicStoreCopyValue(store
, key
);
2759 if (isA_CFDictionary(dict
) &&
2760 (CFDictionaryContainsKey(dict
, CFSTR("*QUIET*")) ||
2761 CFDictionaryContainsKey(dict
, CFSTR("*TIMEOUT*")))) {
2770 ok
= SCDynamicStoreNotifyWait(store
);
2772 SCLog(TRUE
, LOG_ERR
,
2773 CFSTR("SCDynamicStoreNotifyWait() failed: %s"), SCErrorString(SCError()));
2786 CFArrayRef
/* of SCNetworkInterfaceRef's */
2787 SCNetworkInterfaceCopyAll()
2789 CFMutableArrayRef all_interfaces
;
2790 CFArrayRef new_interfaces
;
2791 SCPreferencesRef prefs
;
2793 /* initialize runtime */
2794 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
2796 /* wait for IOKit to quiesce */
2797 pthread_once(&iokit_quiet
, __waitForInterfaces
);
2799 all_interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2801 // get Ethernet, Firewire, and AirPort interfaces
2802 new_interfaces
= __SCNetworkInterfaceCopyAll_IONetworkInterface();
2803 if (new_interfaces
!= NULL
) {
2804 add_interfaces(all_interfaces
, new_interfaces
);
2805 CFRelease(new_interfaces
);
2808 // get Modem interfaces
2809 new_interfaces
= __SCNetworkInterfaceCopyAll_Modem();
2810 if (new_interfaces
!= NULL
) {
2811 add_interfaces(all_interfaces
, new_interfaces
);
2812 CFRelease(new_interfaces
);
2815 // get serial (RS232) interfaces
2816 new_interfaces
= __SCNetworkInterfaceCopyAll_RS232();
2817 if (new_interfaces
!= NULL
) {
2818 add_interfaces(all_interfaces
, new_interfaces
);
2819 CFRelease(new_interfaces
);
2822 // get virtual network interfaces (Bond, VLAN)
2823 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterfaceCopyAll"), NULL
);
2824 if (prefs
!= NULL
) {
2825 new_interfaces
= SCBondInterfaceCopyAll(prefs
);
2826 if (new_interfaces
!= NULL
) {
2827 add_interfaces(all_interfaces
, new_interfaces
);
2828 CFRelease(new_interfaces
);
2831 new_interfaces
= SCVLANInterfaceCopyAll(prefs
);
2832 if (new_interfaces
!= NULL
) {
2833 add_interfaces(all_interfaces
, new_interfaces
);
2834 CFRelease(new_interfaces
);
2840 // all interfaces have been identified, order and return
2841 sort_interfaces(all_interfaces
);
2843 return all_interfaces
;
2847 CFArrayRef
/* of kSCNetworkInterfaceTypeXXX CFStringRef's */
2848 SCNetworkInterfaceGetSupportedInterfaceTypes(SCNetworkInterfaceRef interface
)
2851 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2853 if (!isA_SCNetworkInterface(interface
)) {
2854 _SCErrorSet(kSCStatusInvalidArgument
);
2858 if (interfacePrivate
->supported_interface_types
!= NULL
) {
2862 i
= findConfiguration(interfacePrivate
->interface_type
);
2863 if (i
!= kCFNotFound
) {
2864 if (configurations
[i
].supported_interfaces
!= doNone
) {
2865 interfacePrivate
->supported_interface_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2866 if (configurations
[i
].supported_interfaces
& do6to4
) {
2867 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceType6to4
);
2869 if (configurations
[i
].supported_interfaces
& doL2TP
) {
2870 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeL2TP
);
2872 if (configurations
[i
].supported_interfaces
& doPPP
) {
2873 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypePPP
);
2875 if (configurations
[i
].supported_interfaces
& doPPTP
) {
2876 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypePPTP
);
2883 return interfacePrivate
->supported_interface_types
;
2887 CFArrayRef
/* of kSCNetworkProtocolTypeXXX CFStringRef's */
2888 SCNetworkInterfaceGetSupportedProtocolTypes(SCNetworkInterfaceRef interface
)
2891 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2893 if (!isA_SCNetworkInterface(interface
)) {
2894 _SCErrorSet(kSCStatusInvalidArgument
);
2898 if (interfacePrivate
->supported_protocol_types
!= NULL
) {
2902 i
= findConfiguration(interfacePrivate
->interface_type
);
2903 if (i
!= kCFNotFound
) {
2904 if (configurations
[i
].supported_protocols
!= doNone
) {
2905 interfacePrivate
->supported_protocol_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2906 if (configurations
[i
].supported_protocols
& doAppleTalk
) {
2907 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeAppleTalk
);
2909 if (configurations
[i
].supported_protocols
& doDNS
) {
2910 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeDNS
);
2912 if (configurations
[i
].supported_protocols
& doIPv4
) {
2913 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeIPv4
);
2915 if (configurations
[i
].supported_protocols
& doIPv6
) {
2916 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeIPv6
);
2918 if (configurations
[i
].supported_protocols
& doProxies
) {
2919 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeProxies
);
2921 if (configurations
[i
].supported_protocols
& doSMB
) {
2922 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeSMB
);
2929 return interfacePrivate
->supported_protocol_types
;
2933 SCNetworkInterfaceRef
2934 SCNetworkInterfaceCreateWithInterface(SCNetworkInterfaceRef child
, CFStringRef interfaceType
)
2936 SCNetworkInterfacePrivateRef childPrivate
= (SCNetworkInterfacePrivateRef
)child
;
2938 SCNetworkInterfacePrivateRef parentPrivate
;
2940 if (!isA_SCNetworkInterface(child
)) {
2941 _SCErrorSet(kSCStatusInvalidArgument
);
2945 if (!isA_CFString(interfaceType
)) {
2946 _SCErrorSet(kSCStatusInvalidArgument
);
2950 childIndex
= findConfiguration(childPrivate
->interface_type
);
2952 parentPrivate
= __SCNetworkInterfaceCreatePrivate(NULL
,
2954 childPrivate
->prefs
,
2955 childPrivate
->serviceID
,
2957 if (parentPrivate
== NULL
) {
2958 _SCErrorSet(kSCStatusFailed
);
2962 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
2963 parentPrivate
->interface_type
= kSCNetworkInterfaceTypePPP
;
2964 parentPrivate
->entity_type
= kSCEntNetPPP
;
2967 if (childIndex
!= kCFNotFound
) {
2968 if (configurations
[childIndex
].ppp_subtype
!= NULL
) {
2969 parentPrivate
->entity_subtype
= *configurations
[childIndex
].ppp_subtype
;
2971 // sorry, the child interface does not support PPP
2975 // if the child's interface type not known, use the child entities "Type"
2976 parentPrivate
->entity_subtype
= childPrivate
->entity_type
;
2979 if (childPrivate
->entity_device
!= NULL
) {
2980 parentPrivate
->entity_device
= CFStringCreateCopy(NULL
, childPrivate
->entity_device
);
2982 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
2983 if ((childIndex
== kCFNotFound
) ||
2984 ((configurations
[childIndex
].supported_interfaces
& doL2TP
) != doL2TP
)) {
2985 // if the child interface does not support L2TP
2988 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeL2TP
;
2989 parentPrivate
->localized_key
= CFSTR("l2tp");
2990 parentPrivate
->entity_type
= kSCValNetInterfaceSubTypeL2TP
; // interface config goes into "L2TP"
2991 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPTP
)) {
2992 if ((childIndex
== kCFNotFound
) ||
2993 ((configurations
[childIndex
].supported_interfaces
& doPPTP
) != doPPTP
)) {
2994 // if the child interface does not support PPTP
2997 parentPrivate
->interface_type
= kSCNetworkInterfaceTypePPTP
;
2998 parentPrivate
->localized_key
= CFSTR("pptp");
2999 parentPrivate
->entity_type
= kSCValNetInterfaceSubTypePPTP
; // interface config goes into "PPTP"
3000 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceType6to4
)) {
3001 if ((childIndex
== kCFNotFound
) ||
3002 ((configurations
[childIndex
].supported_interfaces
& do6to4
) != do6to4
)) {
3003 // if the child interface does not support 6to4
3007 parentPrivate
->interface_type
= kSCNetworkInterfaceType6to4
;
3008 parentPrivate
->localized_key
= CFSTR("6to4");
3009 parentPrivate
->entity_type
= kSCEntNet6to4
;
3010 parentPrivate
->entity_device
= CFRetain(CFSTR("stf0"));
3011 } else if (CFStringFind(interfaceType
, CFSTR("."), 0).location
!= kCFNotFound
) {
3012 // if custom interface type
3013 parentPrivate
->interface_type
= interfaceType
;
3014 parentPrivate
->entity_type
= interfaceType
; // interface config goes into a
3015 // a dictionary with the same
3016 // name as the interfaceType
3018 // unknown interface type
3022 if (childPrivate
->overrides
!= NULL
) {
3023 parentPrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, childPrivate
->overrides
);
3025 parentPrivate
->sort_order
= childPrivate
->sort_order
;
3027 return (SCNetworkInterfaceRef
)parentPrivate
;
3031 CFRelease(parentPrivate
);
3032 _SCErrorSet(kSCStatusInvalidArgument
);
3037 static CFDictionaryRef
3038 __SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface
,
3039 CFStringRef extendedType
)
3041 CFDictionaryRef config
= NULL
;
3042 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3045 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
3046 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
3048 paths
= copyConfigurationPaths(interfacePrivate
, extendedType
);
3049 if (paths
!= NULL
) {
3052 path
= CFArrayGetValueAtIndex(paths
, 0);
3053 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
3057 if (interfacePrivate
->unsaved
!= NULL
) {
3058 config
= CFDictionaryGetValue(interfacePrivate
->unsaved
, extendedType
);
3059 if (config
== (CFDictionaryRef
)kCFNull
) {
3065 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
3074 SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface
)
3076 CFDictionaryRef config
;
3077 CFStringRef defaultType
;
3079 if (!isA_SCNetworkInterface(interface
)) {
3080 _SCErrorSet(kSCStatusInvalidArgument
);
3084 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
3085 if (defaultType
== NULL
) {
3089 config
= __SCNetworkInterfaceGetConfiguration(interface
, defaultType
);
3090 if (config
== NULL
) {
3091 if (CFEqual(defaultType
, kSCEntNetAirPort
)) {
3092 SCNetworkInterfacePrivateRef interfacePrivate
;
3095 // if AirPort interface, check for a per-service config
3096 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3097 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
3098 interfacePrivate
->serviceID
, // service
3099 kSCEntNetAirPort
); // entity
3100 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
3104 if (config
== NULL
) {
3105 _SCErrorSet(kSCStatusOK
);
3113 SCNetworkInterfaceGetExtendedConfiguration(SCNetworkInterfaceRef interface
,
3114 CFStringRef extendedType
)
3116 CFDictionaryRef config
;
3118 if (!isA_SCNetworkInterface(interface
)) {
3119 _SCErrorSet(kSCStatusInvalidArgument
);
3123 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, TRUE
)) {
3124 _SCErrorSet(kSCStatusInvalidArgument
);
3128 config
= __SCNetworkInterfaceGetConfiguration(interface
, extendedType
);
3129 if (config
== NULL
) {
3130 _SCErrorSet(kSCStatusOK
);
3138 SCNetworkInterfaceGetBSDName(SCNetworkInterfaceRef interface
)
3140 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3142 if (!isA_SCNetworkInterface(interface
)) {
3143 _SCErrorSet(kSCStatusInvalidArgument
);
3147 if ((interfacePrivate
->interface
!= NULL
) &&
3148 (interfacePrivate
->interface
!= kSCNetworkInterfaceIPv4
)) {
3149 _SCErrorSet(kSCStatusOK
);
3153 return interfacePrivate
->entity_device
;
3158 SCNetworkInterfaceGetHardwareAddressString(SCNetworkInterfaceRef interface
)
3160 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3162 if (!isA_SCNetworkInterface(interface
)) {
3163 _SCErrorSet(kSCStatusInvalidArgument
);
3167 if ((interfacePrivate
->address
!= NULL
) &&
3168 (interfacePrivate
->addressString
== NULL
)) {
3172 char mac
[sizeof("xx:xx:xx:xx:xx:xx:xx:xx")];
3175 bp
= (uint8_t *)CFDataGetBytePtr(interfacePrivate
->address
);
3176 n
= CFDataGetLength(interfacePrivate
->address
) * 3;
3178 if (n
> sizeof(mac
)) {
3179 mac_p
= CFAllocatorAllocate(NULL
, 0, n
);
3182 for (cp
= mac_p
; n
> 0; n
-= 3) {
3183 cp
+= snprintf(cp
, n
, "%2.2x:", *bp
++);
3186 interfacePrivate
->addressString
= CFStringCreateWithCString(NULL
, mac_p
, kCFStringEncodingUTF8
);
3187 if (mac_p
!= mac
) CFAllocatorDeallocate(NULL
, mac_p
);
3190 return interfacePrivate
->addressString
;
3194 SCNetworkInterfaceRef
3195 SCNetworkInterfaceGetInterface(SCNetworkInterfaceRef interface
)
3197 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3199 if (!isA_SCNetworkInterface(interface
)) {
3200 _SCErrorSet(kSCStatusInvalidArgument
);
3204 return interfacePrivate
->interface
;
3209 SCNetworkInterfaceGetInterfaceType(SCNetworkInterfaceRef interface
)
3211 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3213 if (!isA_SCNetworkInterface(interface
)) {
3214 _SCErrorSet(kSCStatusInvalidArgument
);
3218 return interfacePrivate
->interface_type
;
3223 copy_interface_string(CFBundleRef bundle
, CFStringRef key
, Boolean localized
)
3225 CFStringRef str
= NULL
;
3228 str
= CFBundleCopyLocalizedString(bundle
,
3231 NETWORKINTERFACE_LOCALIZATIONS
);
3233 str
= _SC_CFBundleCopyNonLocalizedString(bundle
,
3236 NETWORKINTERFACE_LOCALIZATIONS
);
3244 copy_display_name(SCNetworkInterfaceRef interface
, Boolean localized
)
3246 CFMutableStringRef local
;
3249 local
= CFStringCreateMutable(NULL
, 0);
3251 while (interface
!= NULL
) {
3252 Boolean added
= FALSE
;
3253 SCNetworkInterfaceRef child
= NULL
;
3254 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3256 if ((interfacePrivate
->interface
!= NULL
) &&
3257 (interfacePrivate
->interface
!= kSCNetworkInterfaceIPv4
)) {
3258 child
= interfacePrivate
->interface
;
3261 if ((bundle
!= NULL
) && (interfacePrivate
->localized_key
!= NULL
)) {
3264 fmt
= copy_interface_string(bundle
, interfacePrivate
->localized_key
, localized
);
3266 CFStringAppendFormat(local
,
3269 interfacePrivate
->localized_arg1
,
3270 interfacePrivate
->localized_arg2
);
3277 (interfacePrivate
->prefs
!= NULL
) &&
3278 (interfacePrivate
->serviceID
!= NULL
) &&
3280 CFDictionaryRef entity
;
3283 // check for (and use) the name of the interface when it
3284 // was last available
3285 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,
3286 interfacePrivate
->serviceID
,
3287 kSCEntNetInterface
);
3288 entity
= SCPreferencesPathGetValue(interfacePrivate
->prefs
, path
);
3290 if (isA_CFDictionary(entity
)) {
3293 name
= CFDictionaryGetValue(entity
, kSCPropUserDefinedName
);
3294 if (isA_CFString(name
)) {
3295 CFStringAppend(local
, name
);
3302 // create (non-)localized name based on the interface type
3303 CFStringAppend(local
, interfacePrivate
->interface_type
);
3305 // ... and, if this is a leaf node, the interface device
3306 if ((interfacePrivate
->entity_device
!= NULL
) && (child
== NULL
)) {
3307 CFStringAppendFormat(local
, NULL
, CFSTR(" (%@)"), interfacePrivate
->entity_device
);
3311 if (child
!= NULL
) {
3312 // if this interface is layered over another
3313 CFStringAppend(local
, CFSTR(" --> "));
3319 name
= CFStringCreateCopy(NULL
, local
);
3328 __SCNetworkInterfaceGetNonLocalizedDisplayName(SCNetworkInterfaceRef interface
)
3330 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3332 if (!isA_SCNetworkInterface(interface
)) {
3333 _SCErrorSet(kSCStatusInvalidArgument
);
3337 if (interfacePrivate
->name
== NULL
) {
3338 interfacePrivate
->name
= copy_display_name(interface
, FALSE
);
3341 return interfacePrivate
->name
;
3346 SCNetworkInterfaceGetLocalizedDisplayName(SCNetworkInterfaceRef interface
)
3348 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3350 if (!isA_SCNetworkInterface(interface
)) {
3351 _SCErrorSet(kSCStatusInvalidArgument
);
3355 if (interfacePrivate
->localized_name
== NULL
) {
3356 interfacePrivate
->localized_name
= copy_display_name(interface
, TRUE
);
3359 return interfacePrivate
->localized_name
;
3365 __SCNetworkInterfaceGetTemplateOverrides(SCNetworkInterfaceRef interface
, CFStringRef interfaceType
)
3367 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3368 CFDictionaryRef overrides
= NULL
;
3370 if (interfacePrivate
->overrides
!= NULL
) {
3371 overrides
= CFDictionaryGetValue(interfacePrivate
->overrides
, interfaceType
);
3379 SCNetworkInterfaceGetTypeID(void)
3381 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
); /* initialize runtime */
3382 return __kSCNetworkInterfaceTypeID
;
3388 __SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface
,
3389 CFStringRef extendedType
,
3390 CFDictionaryRef config
,
3393 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3397 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
3398 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
3400 if (extendedType
== NULL
) {
3401 extendedType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
3402 if (extendedType
== NULL
) {
3407 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
3411 paths
= copyConfigurationPaths(interfacePrivate
, extendedType
);
3412 if (paths
!= NULL
) {
3416 n
= CFArrayGetCount(paths
);
3417 for (i
= 0; i
< n
; i
++) {
3420 path
= CFArrayGetValueAtIndex(paths
, i
);
3421 ok
= __setPrefsConfiguration(interfacePrivate
->prefs
, path
, config
, FALSE
);
3428 // if configuration has been saved
3429 if (interfacePrivate
->unsaved
!= NULL
) {
3430 CFDictionaryRemoveValue(interfacePrivate
->unsaved
, extendedType
);
3431 if (CFDictionaryGetCount(interfacePrivate
->unsaved
) == 0) {
3432 CFRelease(interfacePrivate
->unsaved
);
3433 interfacePrivate
->unsaved
= NULL
;
3441 if (config
== NULL
) {
3442 // remember that we are clearing the configuration
3443 config
= (CFDictionaryRef
)kCFNull
;
3446 if (interfacePrivate
->unsaved
== NULL
) {
3447 interfacePrivate
->unsaved
= CFDictionaryCreateMutable(NULL
,
3449 &kCFTypeDictionaryKeyCallBacks
,
3450 &kCFTypeDictionaryValueCallBacks
);
3452 CFDictionarySetValue(interfacePrivate
->unsaved
, extendedType
, config
);
3455 _SCErrorSet(kSCStatusNoKey
);
3464 SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface
, CFDictionaryRef config
)
3466 CFStringRef defaultType
;
3468 if (!isA_SCNetworkInterface(interface
)) {
3469 _SCErrorSet(kSCStatusInvalidArgument
);
3473 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
3474 if (defaultType
== NULL
) {
3478 return __SCNetworkInterfaceSetConfiguration(interface
, defaultType
, config
, FALSE
);
3483 SCNetworkInterfaceSetExtendedConfiguration(SCNetworkInterfaceRef interface
,
3484 CFStringRef extendedType
,
3485 CFDictionaryRef config
)
3487 if (!isA_SCNetworkInterface(interface
)) {
3488 _SCErrorSet(kSCStatusInvalidArgument
);
3492 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, TRUE
)) {
3496 return __SCNetworkInterfaceSetConfiguration(interface
, extendedType
, config
, FALSE
);
3501 #pragma mark SCNetworkInterface [Refresh Configuration] API
3504 #ifndef kSCEntNetRefreshConfiguration
3505 #define kSCEntNetRefreshConfiguration CFSTR("RefreshConfiguration")
3506 #endif // kSCEntNetRefreshConfiguration
3509 _SCNetworkInterfaceForceConfigurationRefresh(CFStringRef ifName
)
3513 SCDynamicStoreRef store
;
3515 if (!isA_CFString(ifName
)) {
3516 _SCErrorSet(kSCStatusInvalidArgument
);
3520 store
= SCDynamicStoreCreate(NULL
, CFSTR("_SCNetworkInterfaceForceConfigurationRefresh"), NULL
, NULL
);
3521 if (store
== NULL
) {
3525 key
= SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL
,
3526 kSCDynamicStoreDomainState
,
3528 kSCEntNetRefreshConfiguration
);
3529 ok
= SCDynamicStoreNotifyValue(store
, key
);
3537 __SCNetworkInterfaceForceConfigurationRefresh_helper(SCPreferencesRef prefs
, CFStringRef ifName
)
3539 CFDataRef data
= NULL
;
3541 SCPreferencesPrivateRef prefsPrivate
= (SCPreferencesPrivateRef
)prefs
;
3542 uint32_t status
= kSCStatusOK
;
3543 CFDataRef reply
= NULL
;
3545 if (prefsPrivate
->helper
== -1) {
3546 ok
= __SCPreferencesCreate_helper(prefs
);
3552 // serialize the interface name
3553 ok
= _SCSerializeString(ifName
, &data
, NULL
, NULL
);
3558 // have the helper "refresh" the configuration
3559 status
= kSCStatusOK
;
3561 ok
= _SCHelperExec(prefsPrivate
->helper
,
3562 SCHELPER_MSG_INTERFACE_REFRESH
,
3566 if (data
!= NULL
) CFRelease(data
);
3571 if (status
!= kSCStatusOK
) {
3580 if (prefsPrivate
->helper
!= -1) {
3581 _SCHelperClose(prefsPrivate
->helper
);
3582 prefsPrivate
->helper
= -1;
3585 status
= kSCStatusAccessError
;
3590 _SCErrorSet(status
);
3596 SCNetworkInterfaceForceConfigurationRefresh(SCNetworkInterfaceRef interface
)
3599 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3601 if (!isA_SCNetworkInterface(interface
)) {
3602 _SCErrorSet(kSCStatusInvalidArgument
);
3606 ifName
= SCNetworkInterfaceGetBSDName(interface
);
3607 if (ifName
== NULL
) {
3608 _SCErrorSet(kSCStatusInvalidArgument
);
3612 if (interfacePrivate
->prefs
!= NULL
) {
3613 SCPreferencesRef prefs
= interfacePrivate
->prefs
;
3614 SCPreferencesPrivateRef prefsPrivate
= (SCPreferencesPrivateRef
)prefs
;
3616 if (prefsPrivate
->authorizationData
!= NULL
) {
3617 return __SCNetworkInterfaceForceConfigurationRefresh_helper(prefs
, ifName
);
3621 return _SCNetworkInterfaceForceConfigurationRefresh(ifName
);
3626 SCNetworkInterfaceRefreshConfiguration(CFStringRef ifName
)
3628 return _SCNetworkInterfaceForceConfigurationRefresh(ifName
);
3633 #pragma mark SCNetworkInterface Password APIs
3637 getPasswordID(CFDictionaryRef config
, CFStringRef serviceID
)
3639 CFStringRef unique_id
= NULL
;
3641 if (config
!= NULL
) {
3642 CFStringRef encryption
;
3644 encryption
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPasswordEncryption
);
3645 if (isA_CFString(encryption
) &&
3646 CFEqual(encryption
, kSCValNetPPPAuthPasswordEncryptionKeychain
)) {
3647 unique_id
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPassword
);
3650 if (unique_id
== NULL
) {
3651 unique_id
= serviceID
;
3659 copySharedSecretID(CFDictionaryRef config
, CFStringRef serviceID
)
3661 CFMutableStringRef sharedSecret
= NULL
;
3663 if (config
!= NULL
) {
3664 CFStringRef encryption
;
3666 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecretEncryption
);
3667 if (isA_CFString(encryption
) &&
3668 CFEqual(encryption
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) {
3669 sharedSecret
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecret
);
3670 if (sharedSecret
!= NULL
) {
3671 CFRetain(sharedSecret
);
3676 if (sharedSecret
== NULL
) {
3677 CFStringRef unique_id
;
3679 unique_id
= getPasswordID(config
, serviceID
);
3680 sharedSecret
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
3681 CFStringAppend(sharedSecret
, CFSTR(".SS"));
3684 return sharedSecret
;
3689 checkInterfacePassword(SCNetworkInterfaceRef interface
,
3690 SCNetworkInterfacePasswordType passwordType
,
3691 SCPreferencesRef
*prefs
,
3692 CFStringRef
*serviceID
)
3694 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3696 if (!isA_SCNetworkInterface(interface
)) {
3697 _SCErrorSet(kSCStatusInvalidArgument
);
3701 *serviceID
= interfacePrivate
->serviceID
;
3702 if (*serviceID
== NULL
) {
3703 _SCErrorSet(kSCStatusInvalidArgument
);
3707 *prefs
= interfacePrivate
->prefs
;
3708 if (*prefs
== NULL
) {
3709 _SCErrorSet(kSCStatusInvalidArgument
);
3713 switch (passwordType
) {
3714 case kSCNetworkInterfacePasswordTypePPP
: {
3715 CFStringRef interfaceType
;
3717 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
3718 if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
3719 _SCErrorSet(kSCStatusInvalidArgument
);
3725 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
3726 CFStringRef interfaceType
;
3728 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
3729 if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
3730 _SCErrorSet(kSCStatusInvalidArgument
);
3734 interface
= SCNetworkInterfaceGetInterface(interface
);
3735 if (interface
== NULL
) {
3736 _SCErrorSet(kSCStatusInvalidArgument
);
3740 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
3741 if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
3742 _SCErrorSet(kSCStatusInvalidArgument
);
3748 case kSCNetworkInterfacePasswordTypeEAPOL
: {
3761 SCNetworkInterfaceCheckPassword(SCNetworkInterfaceRef interface
,
3762 SCNetworkInterfacePasswordType passwordType
)
3764 Boolean exists
= FALSE
;
3765 SCPreferencesRef prefs
= NULL
;
3766 CFStringRef serviceID
= NULL
;
3768 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
3772 switch (passwordType
) {
3773 case kSCNetworkInterfacePasswordTypePPP
: {
3774 CFDictionaryRef config
;
3775 CFStringRef unique_id
;
3777 // get configuration
3778 config
= SCNetworkInterfaceGetConfiguration(interface
);
3781 unique_id
= getPasswordID(config
, serviceID
);
3784 exists
= __extract_password(prefs
,
3786 kSCPropNetPPPAuthPassword
,
3787 kSCPropNetPPPAuthPasswordEncryption
,
3788 kSCValNetPPPAuthPasswordEncryptionKeychain
,
3794 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
3795 CFDictionaryRef config
;
3796 CFStringRef shared_id
;
3798 // get configuration
3799 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
3801 // get sharedSecret ID
3802 shared_id
= copySharedSecretID(config
, serviceID
);
3805 exists
= __extract_password(prefs
,
3807 kSCPropNetIPSecSharedSecret
,
3808 kSCPropNetIPSecSharedSecretEncryption
,
3809 kSCValNetIPSecSharedSecretEncryptionKeychain
,
3812 CFRelease(shared_id
);
3816 case kSCNetworkInterfacePasswordTypeEAPOL
: {
3817 CFDictionaryRef config
;
3818 CFStringRef unique_id
= NULL
;
3820 // get configuration
3821 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
3823 // get 802.1X identifier
3824 if (config
!= NULL
) {
3825 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
3827 if (!isA_CFString(unique_id
)) {
3832 exists
= _SCPreferencesSystemKeychainPasswordItemExists(prefs
, unique_id
);
3837 _SCErrorSet(kSCStatusInvalidArgument
);
3846 SCNetworkInterfaceCopyPassword(SCNetworkInterfaceRef interface
,
3847 SCNetworkInterfacePasswordType passwordType
)
3849 CFDataRef password
= NULL
;
3850 SCPreferencesRef prefs
= NULL
;
3851 CFStringRef serviceID
= NULL
;
3853 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
3857 switch (passwordType
) {
3858 case kSCNetworkInterfacePasswordTypePPP
: {
3859 CFDictionaryRef config
;
3860 CFStringRef unique_id
;
3862 // get configuration
3863 config
= SCNetworkInterfaceGetConfiguration(interface
);
3866 unique_id
= getPasswordID(config
, serviceID
);
3869 (void) __extract_password(prefs
,
3871 kSCPropNetPPPAuthPassword
,
3872 kSCPropNetPPPAuthPasswordEncryption
,
3873 kSCValNetPPPAuthPasswordEncryptionKeychain
,
3879 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
3880 CFDictionaryRef config
;
3881 CFStringRef shared_id
;
3883 // get configuration
3884 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
3886 // get sharedSecret ID
3887 shared_id
= copySharedSecretID(config
, serviceID
);
3890 (void) __extract_password(prefs
,
3892 kSCPropNetIPSecSharedSecret
,
3893 kSCPropNetIPSecSharedSecretEncryption
,
3894 kSCValNetIPSecSharedSecretEncryptionKeychain
,
3898 CFRelease(shared_id
);
3902 case kSCNetworkInterfacePasswordTypeEAPOL
: {
3903 CFDictionaryRef config
;
3904 CFStringRef unique_id
= NULL
;
3906 // get configuration
3907 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
3909 // get 802.1X identifier
3910 if (config
!= NULL
) {
3911 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
3913 if (!isA_CFString(unique_id
)) {
3914 _SCErrorSet(kSCStatusFailed
);
3919 password
= _SCPreferencesSystemKeychainPasswordItemCopy(prefs
, unique_id
);
3924 _SCErrorSet(kSCStatusInvalidArgument
);
3933 SCNetworkInterfaceRemovePassword(SCNetworkInterfaceRef interface
,
3934 SCNetworkInterfacePasswordType passwordType
)
3937 SCPreferencesRef prefs
= NULL
;
3938 CFStringRef serviceID
= NULL
;
3940 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
3944 switch (passwordType
) {
3945 case kSCNetworkInterfacePasswordTypePPP
: {
3946 CFDictionaryRef config
;
3947 CFStringRef unique_id
;
3949 // get configuration
3950 config
= SCNetworkInterfaceGetConfiguration(interface
);
3953 unique_id
= getPasswordID(config
, serviceID
);
3956 ok
= _SCPreferencesSystemKeychainPasswordItemRemove(prefs
, unique_id
);
3958 CFMutableDictionaryRef newConfig
;
3960 if (config
!= NULL
) {
3961 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
3962 CFDictionaryRemoveValue(newConfig
, kSCPropNetPPPAuthPassword
);
3963 CFDictionaryRemoveValue(newConfig
, kSCPropNetPPPAuthPasswordEncryption
);
3964 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
3965 CFRelease(newConfig
);
3971 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
3972 CFDictionaryRef config
;
3973 CFStringRef shared_id
;
3975 // get configuration
3976 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
3978 // get sharedSecret ID
3979 shared_id
= copySharedSecretID(config
, serviceID
);
3982 ok
= _SCPreferencesSystemKeychainPasswordItemRemove(prefs
, shared_id
);
3984 CFMutableDictionaryRef newConfig
;
3986 if (config
!= NULL
) {
3987 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
3988 CFDictionaryRemoveValue(newConfig
, kSCPropNetIPSecSharedSecret
);
3989 CFDictionaryRemoveValue(newConfig
, kSCPropNetIPSecSharedSecretEncryption
);
3990 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
3993 CFRelease(newConfig
);
3997 CFRelease(shared_id
);
4001 case kSCNetworkInterfacePasswordTypeEAPOL
: {
4002 CFDictionaryRef config
;
4003 CFStringRef unique_id
= NULL
;
4005 // get configuration
4006 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
4008 // get 802.1X identifier
4009 if (config
!= NULL
) {
4010 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
4012 if (!isA_CFString(unique_id
)) {
4013 _SCErrorSet(kSCStatusFailed
);
4018 ok
= _SCPreferencesSystemKeychainPasswordItemRemove(prefs
, unique_id
);
4023 _SCErrorSet(kSCStatusInvalidArgument
);
4032 SCNetworkInterfaceSetPassword(SCNetworkInterfaceRef interface
,
4033 SCNetworkInterfacePasswordType passwordType
,
4035 CFDictionaryRef options
)
4037 CFStringRef account
= NULL
;
4038 CFDictionaryRef config
;
4039 CFStringRef description
= NULL
;
4040 CFStringRef label
= NULL
;
4042 SCPreferencesRef prefs
= NULL
;
4043 CFStringRef serviceID
= NULL
;
4045 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
4049 switch (passwordType
) {
4050 case kSCNetworkInterfacePasswordTypePPP
: {
4051 SCNetworkServiceRef service
= NULL
;
4052 CFStringRef unique_id
;
4054 // get configuration
4055 config
= SCNetworkInterfaceGetConfiguration(interface
);
4058 unique_id
= getPasswordID(config
, serviceID
);
4060 // get "Account", "Name", "Kind"
4061 if (config
!= NULL
) {
4062 // auth name --> keychain "Account"
4063 account
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthName
);
4065 // PPP [user defined] "name" --> keychain "Name"
4066 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
4069 if (label
== NULL
) {
4070 // service name --> keychain "Name"
4071 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
4076 label
= SCNetworkServiceGetName(service
);
4077 if (label
== NULL
) {
4078 // interface name --> keychain "Name"
4079 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
4083 if (bundle
!= NULL
) {
4084 // "PPP Password" --> keychain "Kind"
4085 description
= CFBundleCopyLocalizedString(bundle
,
4086 CFSTR("KEYCHAIN_PPP_PASSWORD"),
4087 CFSTR("PPP Password"),
4092 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
4094 (label
!= NULL
) ? label
: CFSTR("PPP"),
4095 (description
!= NULL
) ? description
: CFSTR("PPP Password"),
4100 CFMutableDictionaryRef newConfig
;
4102 if (config
!= NULL
) {
4103 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
4105 newConfig
= CFDictionaryCreateMutable(NULL
,
4107 &kCFTypeDictionaryKeyCallBacks
,
4108 &kCFTypeDictionaryValueCallBacks
);
4110 CFDictionarySetValue(newConfig
,
4111 kSCPropNetPPPAuthPassword
,
4113 CFDictionarySetValue(newConfig
,
4114 kSCPropNetPPPAuthPasswordEncryption
,
4115 kSCValNetPPPAuthPasswordEncryptionKeychain
);
4116 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
4117 CFRelease(newConfig
);
4120 if (description
!= NULL
) CFRelease(description
);
4121 if (service
!= NULL
) CFRelease(service
);
4125 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
4126 SCNetworkServiceRef service
= NULL
;
4127 CFStringRef shared_id
;
4129 // get configuration
4130 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
4132 // get sharedSecret ID
4133 shared_id
= copySharedSecretID(config
, serviceID
);
4135 // get "Name", "Kind"
4136 if (config
!= NULL
) {
4137 // PPP [user defined] "name" --> keychain "Name"
4138 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
4141 if (label
== NULL
) {
4142 // service name --> keychain "Name"
4143 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
4148 label
= SCNetworkServiceGetName(service
);
4149 if (label
== NULL
) {
4150 // interface name --> keychain "Name"
4151 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
4155 if (bundle
!= NULL
) {
4156 // "IPSec Shared Secret" --> keychain "Kind"
4157 description
= CFBundleCopyLocalizedString(bundle
,
4158 CFSTR("KEYCHAIN_IPSEC_SHARED_SECRET"),
4159 CFSTR("IPSec Shared Secret"),
4164 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
4166 (label
!= NULL
) ? label
: CFSTR("PPP"),
4167 (description
!= NULL
) ? description
: CFSTR("IPSec Shared Secret"),
4172 CFMutableDictionaryRef newConfig
= NULL
;
4174 if (config
!= NULL
) {
4175 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
4177 newConfig
= CFDictionaryCreateMutable(NULL
,
4179 &kCFTypeDictionaryKeyCallBacks
,
4180 &kCFTypeDictionaryValueCallBacks
);
4182 CFDictionarySetValue(newConfig
,
4183 kSCPropNetIPSecSharedSecret
,
4185 CFDictionarySetValue(newConfig
,
4186 kSCPropNetIPSecSharedSecretEncryption
,
4187 kSCValNetIPSecSharedSecretEncryptionKeychain
);
4188 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
4191 CFRelease(newConfig
);
4194 if (description
!= NULL
) CFRelease(description
);
4195 if (service
!= NULL
) CFRelease(service
);
4196 CFRelease(shared_id
);
4200 case kSCNetworkInterfacePasswordTypeEAPOL
: {
4201 CFStringRef unique_id
= NULL
;
4203 // get configuration
4204 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
4206 // get 802.1X identifier
4207 if (config
!= NULL
) {
4208 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
4210 if (isA_CFString(unique_id
)) {
4211 CFRetain(unique_id
);
4215 uuid
= CFUUIDCreate(NULL
);
4216 unique_id
= CFUUIDCreateString(NULL
, uuid
);
4220 // get "Name", "Kind"
4221 if (bundle
!= NULL
) {
4222 // "802.1X Password" --> keychain "Name"
4223 label
= CFBundleCopyLocalizedString(bundle
,
4224 CFSTR("KEYCHAIN_EAPOL_PASSWORD"),
4225 CFSTR("802.1X Password"),
4227 // "Internet Connect" --> keychain "Kind"
4228 description
= CFBundleCopyLocalizedString(bundle
,
4229 CFSTR("KEYCHAIN_INTERNET_CONNECT"),
4230 CFSTR("Internet Connect"),
4235 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
4237 (label
!= NULL
) ? label
: CFSTR("802.1X Password"),
4238 (description
!= NULL
) ? description
: CFSTR("Internet Connect"),
4243 CFMutableDictionaryRef newConfig
= NULL
;
4245 if (config
!= NULL
) {
4246 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
4248 newConfig
= CFDictionaryCreateMutable(NULL
,
4250 &kCFTypeDictionaryKeyCallBacks
,
4251 &kCFTypeDictionaryValueCallBacks
);
4253 CFDictionarySetValue(newConfig
,
4254 kEAPClientPropUserPasswordKeychainItemID
,
4256 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
4259 CFRelease(newConfig
);
4262 CFRelease(unique_id
);
4263 if (label
!= NULL
) CFRelease(label
);
4264 if (description
!= NULL
) CFRelease(description
);
4269 _SCErrorSet(kSCStatusInvalidArgument
);
4278 #pragma mark SCNetworkInterface [InterfaceNamer] SPIs
4281 SCNetworkInterfaceRef
4282 _SCNetworkInterfaceCreateWithIONetworkInterfaceObject(io_object_t if_obj
)
4284 SCNetworkInterfaceRef interface
;
4286 /* initialize runtime */
4287 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4289 interface
= createInterface(if_obj
, processNetworkInterface
);
4295 _SCNetworkInterfaceGetHardwareAddress(SCNetworkInterfaceRef interface
)
4297 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4299 return interfacePrivate
->address
;
4304 _SCNetworkInterfaceGetIOInterfaceType(SCNetworkInterfaceRef interface
)
4306 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4308 return interfacePrivate
->type
;
4313 _SCNetworkInterfaceGetIOInterfaceUnit(SCNetworkInterfaceRef interface
)
4315 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4317 return interfacePrivate
->unit
;
4322 _SCNetworkInterfaceGetIOPath(SCNetworkInterfaceRef interface
)
4324 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4326 return interfacePrivate
->path
;
4331 _SCNetworkInterfaceIsBuiltin(SCNetworkInterfaceRef interface
)
4333 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4335 return interfacePrivate
->builtin
;
4340 #pragma mark SCNetworkInterface SPIs
4343 _SCNetworkInterfaceIsModemV92(SCNetworkInterfaceRef interface
)
4345 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4347 return interfacePrivate
->modemIsV92
;
4352 #pragma mark SCNetworkInterface [internal] SPIs
4356 SCNetworkInterfacePrivateRef
4357 __SCNetworkInterfaceCreateCopy(CFAllocatorRef allocator
,
4358 SCNetworkInterfaceRef interface
,
4359 SCPreferencesRef prefs
,
4360 CFStringRef serviceID
)
4362 SCNetworkInterfacePrivateRef oldPrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4363 SCNetworkInterfacePrivateRef newPrivate
;
4365 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
4366 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4368 newPrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, prefs
, serviceID
, NULL
);
4369 newPrivate
->interface_type
= oldPrivate
->interface_type
;
4370 if (oldPrivate
->interface
!= NULL
) {
4371 newPrivate
->interface
= (SCNetworkInterfaceRef
)__SCNetworkInterfaceCreateCopy(NULL
, // allocator
4372 oldPrivate
->interface
, // interface
4373 prefs
, // [new] prefs
4374 serviceID
); // [new] serviceID
4376 if (oldPrivate
->name
!= NULL
) {
4377 newPrivate
->name
= CFRetain(oldPrivate
->name
);
4379 if (oldPrivate
->localized_name
!= NULL
) {
4380 newPrivate
->localized_name
= CFRetain(oldPrivate
->localized_name
);
4382 newPrivate
->localized_key
= oldPrivate
->localized_key
;
4383 if (oldPrivate
->localized_arg1
!= NULL
) {
4384 newPrivate
->localized_arg1
= CFRetain(oldPrivate
->localized_arg1
);
4386 if (oldPrivate
->localized_arg2
!= NULL
) {
4387 newPrivate
->localized_arg2
= CFRetain(oldPrivate
->localized_arg2
);
4389 if (oldPrivate
->unsaved
!= NULL
) {
4390 newPrivate
->unsaved
= CFDictionaryCreateMutableCopy(NULL
, 0, oldPrivate
->unsaved
);
4392 if (oldPrivate
->entity_device
!= NULL
) {
4393 newPrivate
->entity_device
= CFRetain(oldPrivate
->entity_device
);
4395 newPrivate
->entity_type
= oldPrivate
->entity_type
;
4396 newPrivate
->entity_subtype
= oldPrivate
->entity_subtype
;
4397 if (oldPrivate
->supported_interface_types
!= NULL
) {
4398 newPrivate
->supported_interface_types
= CFArrayCreateMutableCopy(NULL
, 0, oldPrivate
->supported_interface_types
);
4400 if (oldPrivate
->supported_protocol_types
!= NULL
) {
4401 newPrivate
->supported_protocol_types
= CFArrayCreateMutableCopy(NULL
, 0, oldPrivate
->supported_protocol_types
);
4403 if (oldPrivate
->address
!= NULL
) {
4404 newPrivate
->address
= CFRetain(oldPrivate
->address
);
4406 newPrivate
->builtin
= oldPrivate
->builtin
;
4407 if (oldPrivate
->location
!= NULL
) {
4408 newPrivate
->location
= CFRetain(oldPrivate
->location
);
4410 if (oldPrivate
->path
!= NULL
) {
4411 newPrivate
->path
= CFRetain(oldPrivate
->path
);
4413 if (oldPrivate
->overrides
!= NULL
) {
4414 newPrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, oldPrivate
->overrides
);
4416 newPrivate
->modemIsV92
= oldPrivate
->modemIsV92
;
4417 newPrivate
->supportsBond
= oldPrivate
->supportsBond
;
4418 newPrivate
->supportsVLAN
= oldPrivate
->supportsVLAN
;
4419 if (oldPrivate
->type
!= NULL
) {
4420 newPrivate
->type
= CFRetain(oldPrivate
->type
);
4422 if (oldPrivate
->unit
!= NULL
) {
4423 newPrivate
->unit
= CFRetain(oldPrivate
->unit
);
4425 newPrivate
->sort_order
= oldPrivate
->sort_order
;
4426 if (oldPrivate
->bond
.interfaces
!= NULL
) {
4427 newPrivate
->bond
.interfaces
= CFRetain(oldPrivate
->bond
.interfaces
);
4429 if (oldPrivate
->bond
.mode
!= NULL
) {
4430 newPrivate
->bond
.mode
= CFRetain(oldPrivate
->bond
.mode
);
4432 if (oldPrivate
->bond
.options
!= NULL
) {
4433 newPrivate
->bond
.options
= CFRetain(oldPrivate
->bond
.options
);
4435 if (oldPrivate
->vlan
.interface
!= NULL
) {
4436 newPrivate
->vlan
.interface
= CFRetain(oldPrivate
->vlan
.interface
);
4438 if (oldPrivate
->vlan
.tag
!= NULL
) {
4439 newPrivate
->vlan
.tag
= CFRetain(oldPrivate
->vlan
.tag
);
4441 if (oldPrivate
->vlan
.options
!= NULL
) {
4442 newPrivate
->vlan
.options
= CFRetain(oldPrivate
->vlan
.options
);
4451 __SCNetworkInterfaceCopyDeepConfiguration(SCNetworkInterfaceRef interface
)
4453 CFMutableArrayRef configs
;
4455 configs
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4457 while (interface
!= NULL
) {
4458 CFStringRef defaultType
;
4459 CFMutableDictionaryRef interfaceConfiguration
;
4461 interfaceConfiguration
= CFDictionaryCreateMutable(NULL
,
4463 &kCFTypeDictionaryKeyCallBacks
,
4464 &kCFTypeDictionaryValueCallBacks
);
4466 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
4467 if (defaultType
!= NULL
) {
4468 CFDictionaryRef config
;
4469 CFArrayRef extendedTypes
;
4471 config
= __SCNetworkInterfaceGetConfiguration(interface
, defaultType
);
4472 if (config
== NULL
) {
4473 config
= (CFDictionaryRef
)kCFNull
;
4475 CFDictionarySetValue(interfaceConfiguration
, defaultType
, config
);
4477 extendedTypes
= extendedConfigurationTypes(interface
);
4478 if (extendedTypes
!= NULL
) {
4482 n
= CFArrayGetCount(extendedTypes
);
4483 for (i
= 0; i
< n
; i
++) {
4484 CFStringRef extendedType
;
4486 extendedType
= CFArrayGetValueAtIndex(extendedTypes
, i
);
4487 config
= __SCNetworkInterfaceGetConfiguration(interface
, extendedType
);
4488 if (config
== NULL
) {
4489 config
= (CFDictionaryRef
)kCFNull
;
4491 CFDictionarySetValue(interfaceConfiguration
, extendedType
, config
);
4494 CFRelease(extendedTypes
);
4498 CFArrayAppendValue(configs
, interfaceConfiguration
);
4499 CFRelease(interfaceConfiguration
);
4501 interface
= SCNetworkInterfaceGetInterface(interface
);
4510 __SCNetworkInterfaceSetDeepConfiguration(SCNetworkInterfaceRef interface
, CFArrayRef configs
)
4514 for (i
= 0; interface
!= NULL
; i
++) {
4515 CFStringRef defaultType
;
4516 CFDictionaryRef interfaceConfiguration
;
4518 interfaceConfiguration
= (configs
!= NULL
) ? CFArrayGetValueAtIndex(configs
, i
) : NULL
;
4520 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
4521 if (defaultType
!= NULL
) {
4522 CFDictionaryRef config
;
4523 CFArrayRef extendedTypes
;
4525 config
= (interfaceConfiguration
!= NULL
) ? CFDictionaryGetValue(interfaceConfiguration
, defaultType
)
4527 if (config
== (CFDictionaryRef
)kCFNull
) {
4530 if (!__SCNetworkInterfaceSetConfiguration(interface
, defaultType
, config
, TRUE
)) {
4531 SCLog(TRUE
, LOG_DEBUG
,
4532 CFSTR("__SCNetworkInterfaceSetDeepConfiguration __SCNetworkInterfaceSetConfiguration() failed, interface=%@, type=%@"),
4537 extendedTypes
= extendedConfigurationTypes(interface
);
4538 if (extendedTypes
!= NULL
) {
4542 n
= CFArrayGetCount(extendedTypes
);
4543 for (j
= 0; j
< n
; j
++) {
4544 CFStringRef extendedType
;
4546 extendedType
= CFArrayGetValueAtIndex(extendedTypes
, j
);
4547 config
= (interfaceConfiguration
!= NULL
) ? CFDictionaryGetValue(interfaceConfiguration
, extendedType
)
4549 if (config
== (CFDictionaryRef
)kCFNull
) {
4552 if (!__SCNetworkInterfaceSetConfiguration(interface
, extendedType
, config
, TRUE
)) {
4553 SCLog(TRUE
, LOG_DEBUG
,
4554 CFSTR("__SCNetworkInterfaceSetDeepConfiguration __SCNetworkInterfaceSetConfiguration() failed, interface=%@, type=%@"),
4560 CFRelease(extendedTypes
);
4564 interface
= SCNetworkInterfaceGetInterface(interface
);