2 * Copyright (c) 2002-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 * October 21, 2000 Allan Nathanson <ajn@apple.com>
33 #define KERNEL_PRIVATE
34 #include <sys/ioctl.h>
36 #include <sys/socket.h>
37 #include <net/ethernet.h>
39 #include <net/if_vlan_var.h>
40 #include <net/if_media.h>
41 #include <net/if_types.h>
43 #include <SystemConfiguration/SystemConfiguration.h>
44 #include <SystemConfiguration/SCPrivate.h> // for SCLog()
45 #include "SCNetworkConfigurationInternal.h" // for __SCNetworkInterfaceCreatePrivate
46 #include <SystemConfiguration/SCValidation.h>
48 #include <IOKit/IOKitLib.h>
49 #include <IOKit/network/IONetworkInterface.h>
50 #include <IOKit/network/IONetworkController.h>
51 #include "dy_framework.h"
54 static const struct ifmedia_description ifm_subtype_shared_descriptions
[] =
55 IFM_SUBTYPE_SHARED_DESCRIPTIONS
;
57 static const struct ifmedia_description ifm_subtype_ethernet_descriptions
[] =
58 IFM_SUBTYPE_ETHERNET_DESCRIPTIONS
;
60 static const struct ifmedia_description ifm_subtype_ieee80211_descriptions
[] =
61 IFM_SUBTYPE_IEEE80211_DESCRIPTIONS
;
63 static const struct ifmedia_description ifm_shared_option_descriptions
[] =
64 IFM_SHARED_OPTION_DESCRIPTIONS
;
66 static const struct ifmedia_description ifm_subtype_ethernet_option_descriptions
[] =
67 IFM_SUBTYPE_ETHERNET_OPTION_DESCRIPTIONS
;
69 static const struct ifmedia_description ifm_subtype_ieee80211_option_descriptions
[] =
70 IFM_SUBTYPE_IEEE80211_OPTION_DESCRIPTIONS
;
74 __freeMediaList(struct ifmediareq
*ifm
)
76 if (ifm
->ifm_ulist
!= NULL
) CFAllocatorDeallocate(NULL
, ifm
->ifm_ulist
);
77 CFAllocatorDeallocate(NULL
, ifm
);
82 static struct ifmediareq
*
83 __copyMediaList(CFStringRef interfaceName
)
85 struct ifmediareq
*ifm
;
89 ifm
= (struct ifmediareq
*)CFAllocatorAllocate(NULL
, sizeof(struct ifmediareq
), 0);
90 bzero((void *)ifm
, sizeof(*ifm
));
92 if (_SC_cfstring_to_cstring(interfaceName
, ifm
->ifm_name
, sizeof(ifm
->ifm_name
), kCFStringEncodingASCII
) == NULL
) {
93 SCLog(TRUE
, LOG_ERR
, CFSTR("could not convert interface name"));
97 sock
= socket(AF_INET
, SOCK_DGRAM
, 0);
99 SCLog(TRUE
, LOG_ERR
, CFSTR("socket() failed: %s"), strerror(errno
));
103 if (ioctl(sock
, SIOCGIFMEDIA
, (caddr_t
)ifm
) == -1) {
104 // SCLog(TRUE, LOG_DEBUG, CFSTR("ioctl(SIOCGIFMEDIA) failed: %s"), strerror(errno));
108 if (ifm
->ifm_count
> 0) {
109 ifm
->ifm_ulist
= (int *)CFAllocatorAllocate(NULL
, ifm
->ifm_count
* sizeof(int), 0);
110 if (ioctl(sock
, SIOCGIFMEDIA
, (caddr_t
)ifm
) == -1) {
111 SCLog(TRUE
, LOG_DEBUG
, CFSTR("ioctl(SIOCGIFMEDIA) failed: %s"), strerror(errno
));
120 if (sock
!= -1) (void)close(sock
);
122 __freeMediaList(ifm
);
124 _SCErrorSet(kSCStatusFailed
);
130 static CFDictionaryRef
131 __createMediaDictionary(int media_options
, Boolean filter
)
133 CFMutableDictionaryRef dict
= NULL
;
135 const struct ifmedia_description
*option_descriptions
= NULL
;
136 CFMutableArrayRef options
= NULL
;
137 const struct ifmedia_description
*subtype_descriptions
= NULL
;
141 ((IFM_SUBTYPE(media_options
) == IFM_NONE
) ||
142 ((IFM_OPTIONS(media_options
) & IFM_LOOP
) != 0))) {
143 return NULL
; /* filter */
146 switch (IFM_TYPE(media_options
)) {
148 option_descriptions
= ifm_subtype_ethernet_option_descriptions
;
149 subtype_descriptions
= ifm_subtype_ethernet_descriptions
;
152 option_descriptions
= ifm_subtype_ieee80211_option_descriptions
;
153 subtype_descriptions
= ifm_subtype_ieee80211_descriptions
;
159 dict
= CFDictionaryCreateMutable(NULL
,
161 &kCFTypeDictionaryKeyCallBacks
,
162 &kCFTypeDictionaryValueCallBacks
);
167 for (i
= 0; !val
&& ifm_subtype_shared_descriptions
[i
].ifmt_string
; i
++) {
168 if (IFM_SUBTYPE(media_options
) == ifm_subtype_shared_descriptions
[i
].ifmt_word
) {
169 val
= CFStringCreateWithCString(NULL
,
170 ifm_subtype_shared_descriptions
[i
].ifmt_string
,
171 kCFStringEncodingASCII
);
176 if (subtype_descriptions
!= NULL
) {
177 for (i
= 0; !val
&& subtype_descriptions
[i
].ifmt_string
; i
++) {
178 if (IFM_SUBTYPE(media_options
) == subtype_descriptions
[i
].ifmt_word
) {
179 val
= CFStringCreateWithCString(NULL
,
180 subtype_descriptions
[i
].ifmt_string
,
181 kCFStringEncodingASCII
);
188 CFDictionaryAddValue(dict
, kSCPropNetEthernetMediaSubType
, val
);
194 options
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
196 while (IFM_OPTIONS(media_options
) != 0) {
198 for (i
= 0; !val
&& ifm_shared_option_descriptions
[i
].ifmt_string
; i
++) {
199 if (IFM_OPTIONS(media_options
) & ifm_shared_option_descriptions
[i
].ifmt_word
) {
200 val
= CFStringCreateWithCString(NULL
,
201 ifm_shared_option_descriptions
[i
].ifmt_string
,
202 kCFStringEncodingASCII
);
203 media_options
&= ~ifm_shared_option_descriptions
[i
].ifmt_word
;
208 if (option_descriptions
!= NULL
) {
209 for (i
= 0; !val
&& option_descriptions
[i
].ifmt_string
; i
++) {
210 if (IFM_OPTIONS(media_options
) & option_descriptions
[i
].ifmt_word
) {
211 val
= CFStringCreateWithCString(NULL
,
212 option_descriptions
[i
].ifmt_string
,
213 kCFStringEncodingASCII
);
214 media_options
&= ~option_descriptions
[i
].ifmt_word
;
221 CFArrayAppendValue(options
, val
);
226 CFDictionaryAddValue(dict
, kSCPropNetEthernetMediaOptions
, options
);
234 __createMediaOptions(CFStringRef interfaceName
, CFDictionaryRef media_options
)
237 struct ifmediareq
*ifm
;
241 const struct ifmedia_description
*option_descriptions
= NULL
;
244 const struct ifmedia_description
*subtype_descriptions
= NULL
;
249 ifm
= __copyMediaList(interfaceName
);
251 if (ifm
->ifm_count
> 0) {
252 ifm_new
= IFM_TYPE(ifm
->ifm_ulist
[0]);
254 __freeMediaList(ifm
);
258 // if we cannot determine the media type for the interface
262 switch (IFM_TYPE(ifm_new
)) {
264 option_descriptions
= ifm_subtype_ethernet_option_descriptions
;
265 subtype_descriptions
= ifm_subtype_ethernet_descriptions
;
268 option_descriptions
= ifm_subtype_ieee80211_option_descriptions
;
269 subtype_descriptions
= ifm_subtype_ieee80211_descriptions
;
275 val
= CFDictionaryGetValue(media_options
, kSCPropNetEthernetMediaSubType
);
276 if (!isA_CFString(val
)) {
280 str
= _SC_cfstring_to_cstring(val
, NULL
, 0, kCFStringEncodingASCII
);
286 for (i
= 0; !match
&& ifm_subtype_shared_descriptions
[i
].ifmt_string
; i
++) {
287 if (strcasecmp(str
, ifm_subtype_shared_descriptions
[i
].ifmt_string
) == 0) {
288 ifm_new
|= ifm_subtype_shared_descriptions
[i
].ifmt_word
;
294 if (subtype_descriptions
!= NULL
) {
295 for (i
= 0; !match
&& subtype_descriptions
[i
].ifmt_string
; i
++) {
296 if (strcasecmp(str
, subtype_descriptions
[i
].ifmt_string
) == 0) {
297 ifm_new
|= subtype_descriptions
[i
].ifmt_word
;
304 CFAllocatorDeallocate(NULL
, str
);
307 return -1; /* if no subtype */
312 options
= CFDictionaryGetValue(media_options
, kSCPropNetEthernetMediaOptions
);
313 if (!isA_CFArray(options
)) {
317 n
= CFArrayGetCount(options
);
318 for (i
= 0; i
< n
; i
++) {
321 val
= CFArrayGetValueAtIndex(options
, i
);
322 if (!isA_CFString(val
)) {
326 str
= _SC_cfstring_to_cstring(val
, NULL
, 0, kCFStringEncodingASCII
);
333 for (j
= 0; !match
&& ifm_shared_option_descriptions
[j
].ifmt_string
; j
++) {
334 if (strcasecmp(str
, ifm_shared_option_descriptions
[j
].ifmt_string
) == 0) {
335 ifm_new
|= ifm_shared_option_descriptions
[j
].ifmt_word
;
341 if (option_descriptions
!= NULL
) {
342 for (j
= 0; !match
&& option_descriptions
[j
].ifmt_string
; j
++) {
343 if (strcasecmp(str
, option_descriptions
[j
].ifmt_string
) == 0) {
344 ifm_new
|= option_descriptions
[j
].ifmt_word
;
351 CFAllocatorDeallocate(NULL
, str
);
354 return -1; /* if no option */
363 SCNetworkInterfaceCopyMediaOptions(SCNetworkInterfaceRef interface
,
364 CFDictionaryRef
*current
,
365 CFDictionaryRef
*active
,
366 CFArrayRef
*available
,
370 struct ifmediareq
*ifm
;
371 CFStringRef interfaceName
;
373 if (!isA_SCNetworkInterface(interface
)) {
374 _SCErrorSet(kSCStatusInvalidArgument
);
378 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
379 if (interfaceName
== NULL
) {
380 SCLog(TRUE
, LOG_ERR
, CFSTR("no interface name"));
381 _SCErrorSet(kSCStatusInvalidArgument
);
385 ifm
= __copyMediaList(interfaceName
);
390 if (active
!= NULL
) *active
= NULL
;
391 if (current
!= NULL
) *current
= NULL
;
392 if (available
!= NULL
) {
393 CFMutableArrayRef media_options
;
395 media_options
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
396 for (i
= 0; i
< ifm
->ifm_count
; i
++) {
397 CFDictionaryRef options
;
399 options
= __createMediaDictionary(ifm
->ifm_ulist
[i
], filter
);
400 if (options
== NULL
) {
404 if ((active
!= NULL
) && (*active
== NULL
) && (ifm
->ifm_active
== ifm
->ifm_ulist
[i
])) {
405 *active
= CFRetain(options
);
408 if ((current
!= NULL
) && (*current
== NULL
) && (ifm
->ifm_current
== ifm
->ifm_ulist
[i
])) {
409 *current
= CFRetain(options
);
412 if (!CFArrayContainsValue(media_options
, CFRangeMake(0, CFArrayGetCount(media_options
)), options
)) {
413 CFArrayAppendValue(media_options
, options
);
418 *available
= (CFArrayRef
)media_options
;
421 if ((active
!= NULL
) && (*active
== NULL
)) {
422 *active
= __createMediaDictionary(ifm
->ifm_active
, FALSE
);
425 if ((current
!= NULL
) && (*current
== NULL
)) {
426 if ((active
!= NULL
) && (ifm
->ifm_active
== ifm
->ifm_current
)) {
427 if (*active
!= NULL
) *current
= CFRetain(*active
);
429 *current
= __createMediaDictionary(ifm
->ifm_current
, FALSE
);
433 __freeMediaList(ifm
);
439 SCNetworkInterfaceCopyMediaSubTypes(CFArrayRef available
)
443 CFMutableArrayRef subTypes
;
445 if (!isA_CFArray(available
)) {
446 _SCErrorSet(kSCStatusInvalidArgument
);
450 subTypes
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
452 n
= CFArrayGetCount(available
);
453 for (i
= 0; i
< n
; i
++) {
454 CFDictionaryRef options
;
457 options
= CFArrayGetValueAtIndex(available
, i
);
458 if (!isA_CFDictionary(options
)) {
462 subType
= CFDictionaryGetValue(options
, kSCPropNetEthernetMediaSubType
);
463 if (!isA_CFString(subType
)) {
467 if (!CFArrayContainsValue(subTypes
, CFRangeMake(0, CFArrayGetCount(subTypes
)), subType
)) {
468 CFArrayAppendValue(subTypes
, subType
);
472 if (CFArrayGetCount(subTypes
) == 0) {
475 _SCErrorSet(kSCStatusOK
);
483 SCNetworkInterfaceCopyMediaSubTypeOptions(CFArrayRef available
,
488 CFMutableArrayRef subTypeOptions
;
490 if (!isA_CFArray(available
)) {
491 _SCErrorSet(kSCStatusInvalidArgument
);
495 subTypeOptions
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
497 n
= CFArrayGetCount(available
);
498 for (i
= 0; i
< n
; i
++) {
499 CFDictionaryRef options
;
500 CFArrayRef mediaOptions
;
501 CFStringRef mediaSubType
;
503 options
= CFArrayGetValueAtIndex(available
, i
);
504 if (!isA_CFDictionary(options
)) {
508 mediaSubType
= CFDictionaryGetValue(options
, kSCPropNetEthernetMediaSubType
);
509 if (!isA_CFString(mediaSubType
) || !CFEqual(subType
, mediaSubType
)) {
513 mediaOptions
= CFDictionaryGetValue(options
, kSCPropNetEthernetMediaOptions
);
514 if (!isA_CFArray(mediaOptions
)) {
518 if (!CFArrayContainsValue(subTypeOptions
, CFRangeMake(0, CFArrayGetCount(subTypeOptions
)), mediaOptions
)) {
519 CFArrayAppendValue(subTypeOptions
, mediaOptions
);
523 if (CFArrayGetCount(subTypeOptions
) == 0) {
524 CFRelease(subTypeOptions
);
525 subTypeOptions
= NULL
;
526 _SCErrorSet(kSCStatusOK
);
529 return subTypeOptions
;
534 __getMTULimits(char ifr_name
[IFNAMSIZ
],
539 io_iterator_t io_iter
= 0;
540 io_registry_entry_t io_interface
= 0;
541 io_registry_entry_t io_controller
= 0;
543 static mach_port_t masterPort
= MACH_PORT_NULL
;
544 CFMutableDictionaryRef matchingDict
;
546 /* look for a matching interface in the IORegistry */
548 if (masterPort
== MACH_PORT_NULL
) {
549 kr
= IOMasterPort(MACH_PORT_NULL
, &masterPort
);
550 if (kr
!= KERN_SUCCESS
) {
555 matchingDict
= IOBSDNameMatching(masterPort
, 0, ifr_name
);
557 /* Note: IOServiceGetMatchingServices consumes a reference on the 'matchingDict' */
558 kr
= IOServiceGetMatchingServices(masterPort
, matchingDict
, &io_iter
);
559 if ((kr
== KERN_SUCCESS
) && io_iter
) {
560 /* should only have a single match */
561 io_interface
= IOIteratorNext(io_iter
);
563 if (io_iter
) IOObjectRelease(io_iter
);
570 * found an interface, get the interface type
572 num
= IORegistryEntryCreateCFProperty(io_interface
, CFSTR(kIOInterfaceType
), NULL
, kNilOptions
);
574 if (isA_CFNumber(num
)) {
575 CFNumberGetValue(num
, kCFNumberIntType
, &ifType
);
581 * ...and the property we are REALLY interested is in the controller,
582 * which is the parent of the interface object.
584 (void)IORegistryEntryGetParentEntry(io_interface
, kIOServicePlane
, &io_controller
);
585 IOObjectRelease(io_interface
);
587 /* if no matching interface */
594 num
= IORegistryEntryCreateCFProperty(io_controller
, CFSTR(kIOMaxPacketSize
), NULL
, kNilOptions
);
596 if (isA_CFNumber(num
)) {
600 * Get the value and subtract the FCS bytes and Ethernet header
601 * sizes from the maximum frame size reported by the controller
602 * to get the MTU size. The 14 byte media header can be found
603 * in the registry, but not the size for the trailing FCS bytes.
605 CFNumberGetValue(num
, kCFNumberIntType
, &value
);
607 if (ifType
== IFT_ETHER
) {
608 value
-= (ETHER_HDR_LEN
+ ETHER_CRC_LEN
);
611 if (mtu_min
) *mtu_min
= IF_MINMTU
;
612 if (mtu_max
) *mtu_max
= value
;
617 IOObjectRelease(io_controller
);
625 SCNetworkInterfaceCopyMTU(SCNetworkInterfaceRef interface
,
631 CFStringRef interfaceName
;
635 if (!isA_SCNetworkInterface(interface
)) {
636 _SCErrorSet(kSCStatusInvalidArgument
);
640 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
641 if (interfaceName
== NULL
) {
642 SCLog(TRUE
, LOG_ERR
, CFSTR("no interface name"));
646 bzero((void *)&ifr
, sizeof(ifr
));
647 if (_SC_cfstring_to_cstring(interfaceName
, ifr
.ifr_name
, sizeof(ifr
.ifr_name
), kCFStringEncodingASCII
) == NULL
) {
648 SCLog(TRUE
, LOG_ERR
, CFSTR("could not convert interface name"));
649 _SCErrorSet(kSCStatusInvalidArgument
);
653 sock
= socket(AF_INET
, SOCK_DGRAM
, 0);
656 SCLog(TRUE
, LOG_ERR
, CFSTR("socket() failed: %s"), strerror(errno
));
660 if (ioctl(sock
, SIOCGIFMTU
, (caddr_t
)&ifr
) == -1) {
662 // SCLog(TRUE, LOG_DEBUG, CFSTR("ioctl(SIOCGIFMTU) failed: %s"), strerror(errno));
666 if (mtu_cur
) *mtu_cur
= ifr
.ifr_mtu
;
667 if (mtu_min
) *mtu_min
= ifr
.ifr_mtu
;
668 if (mtu_max
) *mtu_max
= ifr
.ifr_mtu
;
670 /* get valid MTU range */
672 if (mtu_min
!= NULL
|| mtu_max
!= NULL
) {
673 if (ioctl(sock
, SIOCGIFDEVMTU
, (caddr_t
)&ifr
) == 0) {
674 struct ifdevmtu
* devmtu_p
;
676 devmtu_p
= &ifr
.ifr_devmtu
;
677 if (mtu_min
!= NULL
) {
678 *mtu_min
= (devmtu_p
->ifdm_min
> IF_MINMTU
)
679 ? devmtu_p
->ifdm_min
: IF_MINMTU
;
681 if (mtu_max
!= NULL
) {
682 *mtu_max
= devmtu_p
->ifdm_max
;
685 (void)__getMTULimits(ifr
.ifr_name
, mtu_min
, mtu_max
);
693 if (sock
!= -1) (void)close(sock
);
700 SCNetworkInterfaceSetMediaOptions(SCNetworkInterfaceRef interface
,
704 CFDictionaryRef configuration
;
705 CFMutableDictionaryRef newConfiguration
= NULL
;
708 if (!isA_SCNetworkInterface(interface
)) {
709 _SCErrorSet(kSCStatusInvalidArgument
);
713 configuration
= SCNetworkInterfaceGetConfiguration(interface
);
714 if (configuration
== NULL
) {
715 newConfiguration
= CFDictionaryCreateMutable(NULL
,
717 &kCFTypeDictionaryKeyCallBacks
,
718 &kCFTypeDictionaryValueCallBacks
);
720 newConfiguration
= CFDictionaryCreateMutableCopy(NULL
, 0, configuration
);
721 CFDictionaryRemoveValue(newConfiguration
, kSCResvInactive
);
724 if (subtype
!= NULL
) {
725 CFArrayRef available
= NULL
;
726 CFArrayRef config_options
= options
;
727 CFArrayRef subtypes
= NULL
;
728 CFArrayRef subtype_options
= NULL
;
730 if (options
== NULL
) {
731 config_options
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
734 if (!SCNetworkInterfaceCopyMediaOptions(interface
, NULL
, NULL
, &available
, FALSE
)) {
735 SCLog(_sc_debug
, LOG_DEBUG
, CFSTR("media type / options not available"));
739 if (available
== NULL
) {
740 _SCErrorSet(kSCStatusInvalidArgument
);
744 subtypes
= SCNetworkInterfaceCopyMediaSubTypes(available
);
745 if ((subtypes
== NULL
) ||
746 !CFArrayContainsValue(subtypes
,
747 CFRangeMake(0, CFArrayGetCount(subtypes
)),
749 SCLog(_sc_debug
, LOG_DEBUG
, CFSTR("media type not valid"));
750 _SCErrorSet(kSCStatusInvalidArgument
);
754 subtype_options
= SCNetworkInterfaceCopyMediaSubTypeOptions(available
, subtype
);
755 if ((subtype_options
== NULL
) ||
756 !CFArrayContainsValue(subtype_options
,
757 CFRangeMake(0, CFArrayGetCount(subtype_options
)),
759 SCLog(_sc_debug
, LOG_DEBUG
, CFSTR("media options not valid for \"%@\""), subtype
);
760 _SCErrorSet(kSCStatusInvalidArgument
);
764 CFDictionarySetValue(newConfiguration
, kSCPropNetEthernetMediaSubType
, subtype
);
765 CFDictionarySetValue(newConfiguration
,
766 kSCPropNetEthernetMediaOptions
,
767 (options
!= NULL
) ? options
: config_options
);
773 if (available
!= NULL
) CFRelease(available
);
774 if (subtypes
!= NULL
) CFRelease(subtypes
);
775 if (subtype_options
!= NULL
) CFRelease(subtype_options
);
776 if (options
== NULL
) CFRelease(config_options
);
777 } else if (options
== NULL
) {
778 CFDictionaryRemoveValue(newConfiguration
, kSCPropNetEthernetMediaSubType
);
779 CFDictionaryRemoveValue(newConfiguration
, kSCPropNetEthernetMediaOptions
);
780 if (CFDictionaryGetCount(newConfiguration
) == 0) {
781 CFRelease(newConfiguration
);
782 newConfiguration
= NULL
;
786 SCLog(_sc_debug
, LOG_DEBUG
, CFSTR("media type must be specified with options"));
787 _SCErrorSet(kSCStatusInvalidArgument
);
791 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfiguration
);
794 if (newConfiguration
!= NULL
) CFRelease(newConfiguration
);
800 SCNetworkInterfaceSetMTU(SCNetworkInterfaceRef interface
,
803 CFDictionaryRef configuration
;
806 CFMutableDictionaryRef newConfiguration
= NULL
;
809 if (!isA_SCNetworkInterface(interface
)) {
810 _SCErrorSet(kSCStatusInvalidArgument
);
814 if (!SCNetworkInterfaceCopyMTU(interface
, NULL
, &mtu_min
, &mtu_max
)) {
815 SCLog(_sc_debug
, LOG_DEBUG
, CFSTR("MTU bounds not available"));
819 configuration
= SCNetworkInterfaceGetConfiguration(interface
);
820 if (configuration
== NULL
) {
821 newConfiguration
= CFDictionaryCreateMutable(NULL
,
823 &kCFTypeDictionaryKeyCallBacks
,
824 &kCFTypeDictionaryValueCallBacks
);
826 newConfiguration
= CFDictionaryCreateMutableCopy(NULL
, 0, configuration
);
827 CFDictionaryRemoveValue(newConfiguration
, kSCResvInactive
);
830 if ((mtu
>= mtu_min
) && (mtu
<= mtu_max
)) {
833 num
= CFNumberCreate(NULL
, kCFNumberIntType
, &mtu
);
834 CFDictionarySetValue(newConfiguration
, kSCPropNetEthernetMTU
, num
);
837 } else if (mtu
== 0) {
838 CFDictionaryRemoveValue(newConfiguration
, kSCPropNetEthernetMTU
);
839 if (CFDictionaryGetCount(newConfiguration
) == 0) {
840 CFRelease(newConfiguration
);
841 newConfiguration
= NULL
;
845 SCLog(_sc_debug
, LOG_DEBUG
, CFSTR("MTU out of range"));
846 _SCErrorSet(kSCStatusInvalidArgument
);
850 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfiguration
);
853 if (newConfiguration
!= NULL
) CFRelease(newConfiguration
);
859 // XXXXX Remove the following SPIs as soon as we have migrated all
860 // XXXXX internal users
863 /* DEPRECATED */ Boolean
864 NetworkInterfaceCopyMediaOptions(CFStringRef interfaceName
,
865 CFDictionaryRef
*current
,
866 CFDictionaryRef
*active
,
867 CFArrayRef
*available
,
870 SCNetworkInterfacePrivateRef interfacePrivate
;
873 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
, NULL
);
874 if (interfacePrivate
== NULL
) {
877 interfacePrivate
->entity_device
= CFRetain(interfaceName
);
878 ok
= SCNetworkInterfaceCopyMediaOptions((SCNetworkInterfaceRef
)interfacePrivate
,
883 CFRelease(interfacePrivate
);
888 /* DEPRECATED */ CFArrayRef
889 NetworkInterfaceCopyMediaSubTypes(CFArrayRef available
)
891 return SCNetworkInterfaceCopyMediaSubTypes(available
);
895 /* DEPRECATED */ CFArrayRef
896 NetworkInterfaceCopyMediaSubTypeOptions(CFArrayRef available
,
899 return SCNetworkInterfaceCopyMediaSubTypeOptions(available
, subType
);
903 /* DEPRECATED */ Boolean
904 NetworkInterfaceCopyMTU(CFStringRef interfaceName
,
909 SCNetworkInterfacePrivateRef interfacePrivate
;
912 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
, NULL
);
913 if (interfacePrivate
== NULL
) {
916 interfacePrivate
->entity_device
= CFRetain(interfaceName
);
917 ok
= SCNetworkInterfaceCopyMTU((SCNetworkInterfaceRef
)interfacePrivate
,
921 CFRelease(interfacePrivate
);