X-Git-Url: https://git.saurik.com/apple/configd.git/blobdiff_plain/a5f60add6851c80e3e97d4c50c2855d3be97e589..32d96e3d77d900203b7faba2d7937f8b3472f4d7:/SystemConfiguration.fproj/LinkConfiguration.c diff --git a/SystemConfiguration.fproj/LinkConfiguration.c b/SystemConfiguration.fproj/LinkConfiguration.c new file mode 100644 index 0000000..159b4e0 --- /dev/null +++ b/SystemConfiguration.fproj/LinkConfiguration.c @@ -0,0 +1,571 @@ +/* + * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +/* + * Modification History + * + * October 21, 2000 Allan Nathanson + * - initial revision + */ + + +#include +#include +#include +#include +#include +#include +#include + +#include +#include // for SCLog() +#include + +#include +#include +#include +#include "dy_framework.h" + + +static struct ifmedia_description ifm_subtype_shared_descriptions[] = + IFM_SUBTYPE_SHARED_DESCRIPTIONS; + +static struct ifmedia_description ifm_subtype_ethernet_descriptions[] = + IFM_SUBTYPE_ETHERNET_DESCRIPTIONS; + +static struct ifmedia_description ifm_shared_option_descriptions[] = + IFM_SHARED_OPTION_DESCRIPTIONS; + +static struct ifmedia_description ifm_subtype_ethernet_option_descriptions[] = + IFM_SUBTYPE_ETHERNET_OPTION_DESCRIPTIONS; + + +static char * +cfstring_to_cstring(CFStringRef cfstr, char *buf, int bufLen) +{ + CFIndex len = CFStringGetLength(cfstr); + + if (!buf) { + bufLen = len + 1; + buf = CFAllocatorAllocate(NULL, bufLen, 0); + } + + if (len >= bufLen) { + len = bufLen - 1; + } + + (void)CFStringGetBytes(cfstr, + CFRangeMake(0, len), + kCFStringEncodingASCII, + 0, + FALSE, + buf, + bufLen, + NULL); + buf[len] = '\0'; + + return buf; +} + + + +static CFDictionaryRef +__createMediaDictionary(int media_options, Boolean filter) +{ + CFMutableDictionaryRef dict = NULL; + int i; + CFMutableArrayRef options = NULL; + CFStringRef val; + + if (IFM_TYPE(media_options) != IFM_ETHER) { + return NULL; + } + + if (filter && (IFM_SUBTYPE(media_options) == IFM_NONE)) { + return NULL; /* filter */ + } + + dict = CFDictionaryCreateMutable(NULL, + 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + /* subtype */ + + val = NULL; + for (i=0; !val && ifm_subtype_shared_descriptions[i].ifmt_string; i++) { + if (IFM_SUBTYPE(media_options) == ifm_subtype_shared_descriptions[i].ifmt_word) { + val = CFStringCreateWithCString(NULL, + ifm_subtype_shared_descriptions[i].ifmt_string, + kCFStringEncodingASCII); + break; + } + } + + for (i=0; !val && ifm_subtype_ethernet_descriptions[i].ifmt_string; i++) { + if (IFM_SUBTYPE(media_options) == ifm_subtype_ethernet_descriptions[i].ifmt_word) { + val = CFStringCreateWithCString(NULL, + ifm_subtype_ethernet_descriptions[i].ifmt_string, + kCFStringEncodingASCII); + break; + } + } + + if (val) { + CFDictionaryAddValue(dict, kSCPropNetEthernetMediaSubType, val); + CFRelease(val); + } + + /* options */ + + options = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + + while (IFM_OPTIONS(media_options) != 0) { + if (filter && (IFM_OPTIONS(media_options) & IFM_LOOP)) { + media_options &= ~IFM_LOOP; /* filter */ + continue; + } + + val = NULL; + for (i=0; !val && ifm_shared_option_descriptions[i].ifmt_string; i++) { + if (IFM_OPTIONS(media_options) & ifm_shared_option_descriptions[i].ifmt_word) { + val = CFStringCreateWithCString(NULL, + ifm_shared_option_descriptions[i].ifmt_string, + kCFStringEncodingASCII); + media_options &= ~ifm_shared_option_descriptions[i].ifmt_word; + break; + } + } + + for (i=0; !val && ifm_subtype_ethernet_option_descriptions[i].ifmt_string; i++) { + if (IFM_OPTIONS(media_options) & ifm_subtype_ethernet_option_descriptions[i].ifmt_word) { + val = CFStringCreateWithCString(NULL, + ifm_subtype_ethernet_option_descriptions[i].ifmt_string, + kCFStringEncodingASCII); + media_options &= ~ifm_shared_option_descriptions[i].ifmt_word; + break; + } + } + + if (val) { + CFArrayAppendValue(options, val); + CFRelease(val); + } + } + + CFDictionaryAddValue(dict, kSCPropNetEthernetMediaOptions, options); + CFRelease(options); + + return dict; +} + + +int +__createMediaOptions(CFDictionaryRef media_options) +{ + CFIndex i; + Boolean match; + int ifm_new = IFM_ETHER; + CFArrayRef options; + char *str; + CFStringRef val; + + /* set subtype */ + + val = CFDictionaryGetValue(media_options, kSCPropNetEthernetMediaSubType); + if (!isA_CFString(val)) { + return -1; + } + + str = cfstring_to_cstring(val, NULL, 0); + if (!str) { + return -1; + } + + match = FALSE; + for (i=0; !match && ifm_subtype_shared_descriptions[i].ifmt_string; i++) { + if (strcasecmp(str, ifm_subtype_shared_descriptions[i].ifmt_string) == 0) { + ifm_new |= ifm_subtype_shared_descriptions[i].ifmt_word; + match = TRUE; + break; + } + } + + for (i=0; !match && ifm_subtype_ethernet_descriptions[i].ifmt_string; i++) { + if (strcasecmp(str, ifm_subtype_ethernet_descriptions[i].ifmt_string) == 0) { + ifm_new |= ifm_subtype_ethernet_descriptions[i].ifmt_word; + match = TRUE; + break; + } + } + + CFAllocatorDeallocate(NULL, str); + + if (!match) { + return -1; /* if no subtype */ + } + + /* set options */ + + options = CFDictionaryGetValue(media_options, kSCPropNetEthernetMediaOptions); + if (!isA_CFArray(options)) { + return -1; + } + + for (i=0; i 0) { + media_list = (int *)CFAllocatorAllocate(NULL, ifm.ifm_count * sizeof(int), 0); + ifm.ifm_ulist = media_list; + if (ioctl(sock, SIOCGIFMEDIA, (caddr_t)&ifm) < 0) { + SCLog(TRUE, LOG_DEBUG, CFSTR("ioctl(SIOCGIFMEDIA) failed: %s"), strerror(errno)); + goto done; + } + } + + if (active) *active = NULL; + if (current) *current = NULL; + if (available) { + CFMutableArrayRef media_options; + + media_options = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + for (i=0; i= 0) (void)close(sock); + if (media_list) CFAllocatorDeallocate(NULL, media_list); + + return ok; +} + + +CFArrayRef +NetworkInterfaceCopyMediaSubTypes(CFArrayRef available) +{ + CFIndex i; + CFMutableArrayRef subTypes; + + if (!isA_CFArray(available)) { + return NULL; + } + + subTypes = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + for (i=0; i= 0) (void)close(sock); + + return ok; +}