/* * Function: copy_configured_interface_names * * Purpose: * Return the BSD interface name of all configured interfaces. If * 'entity' is non-NULL, also check that the interface has the specified * extended configuration. */ STATIC CFArrayRef /* of CFStringRef */ copy_configured_interface_names(SCPreferencesRef prefs, CFStringRef entity_name) { SCNetworkSetRef current_set = NULL; int count; int i; CFMutableArrayRef ret_names = NULL; CFRange ret_names_range = { 0 , 0 }; CFArrayRef services = NULL; if (prefs == NULL) { goto done; } current_set = SCNetworkSetCopyCurrent(prefs); if (current_set == NULL) { goto done; } services = SCNetworkSetCopyServices(current_set); if (services == NULL) { goto done; } count = CFArrayGetCount(services); for (i = 0; i < count; i++) { CFStringRef this_if_name; SCNetworkInterfaceRef this_if; SCNetworkServiceRef s; s = (SCNetworkServiceRef)CFArrayGetValueAtIndex(services, i); this_if = SCNetworkServiceGetInterface(s); if (this_if == NULL) { continue; } if (entity_name != NULL && (SCNetworkInterfaceGetExtendedConfiguration(this_if, entity_name) == NULL)) { /* interface doesn't have specified entity */ continue; } this_if_name = SCNetworkInterfaceGetBSDName(this_if); if (this_if_name == NULL) { continue; } if (ret_names == NULL || CFArrayContainsValue(ret_names, ret_names_range, this_if_name) == FALSE) { if (ret_names == NULL) { ret_names = CFArrayCreateMutable(NULL, count, &kCFTypeArrayCallBacks); } CFArrayAppendValue(ret_names, this_if_name); ret_names_range.length++; } } done: my_CFRelease(¤t_set); my_CFRelease(&services); return (ret_names); }
Boolean SCNetworkSetContainsInterface(SCNetworkSetRef set, SCNetworkInterfaceRef interface) { Boolean found = FALSE; CFArrayRef services; services = SCNetworkSetCopyServices(set); if (services != NULL) { found = __SCNetworkServiceExistsForInterface(services, interface); CFRelease(services); } return found; }
Boolean SCNetworkSetSetSelectedVPNService(SCNetworkSetRef set, SCNetworkServiceRef service) { Boolean ok = TRUE; CFArrayRef services; if (!isA_SCNetworkSet(set)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } if (!isA_SCNetworkService(service) || !_SCNetworkServiceIsVPN(service)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } services = SCNetworkSetCopyServices(set); if (services != NULL) { CFIndex i; CFIndex n = CFArrayGetCount(services); if (!CFArrayContainsValue(services, CFRangeMake(0, n), service)) { // if selected service not a member of the current set _SCErrorSet(kSCStatusInvalidArgument); ok = FALSE; goto done; } for (i = 0; ok && (i < n); i++) { SCNetworkServiceRef vpn; vpn = CFArrayGetValueAtIndex(services, i); if (!_SCNetworkServiceIsVPN(vpn)) { // if not VPN service continue; } ok = SCNetworkServiceSetEnabled(vpn, CFEqual(service, vpn)); } } done : if (services != NULL) CFRelease(services); return ok; }
vector<InterfaceInfo> OSXPlatform::interfaces() { vector<InterfaceInfo> result; CFStringRef name = CFSTR("com.codebutler.firesheep.backend"); SCPreferencesRef prefs = SCPreferencesCreate(NULL, name, NULL); SCNetworkSetRef set = SCNetworkSetCopyCurrent(prefs); CFArrayRef services = SCNetworkSetCopyServices(set); int arraySize = CFArrayGetCount(services); for (int i = 0; i < arraySize; i++) { SCNetworkServiceRef service = (SCNetworkServiceRef) CFArrayGetValueAtIndex(services, i); if (SCNetworkServiceGetEnabled(service)) { SCNetworkInterfaceRef iface = SCNetworkServiceGetInterface(service); CFStringRef serviceName = SCNetworkServiceGetName(service); char cServiceName[(CFStringGetLength(serviceName) * 4) + 1]; CFStringGetCString(serviceName, cServiceName, sizeof(cServiceName), kCFStringEncodingUTF8); CFStringRef type = SCNetworkInterfaceGetInterfaceType(iface); if (CFStringCompare(type, CFSTR("Ethernet"), 0) == kCFCompareEqualTo || CFStringCompare(type, CFSTR("IEEE80211"), 0) == kCFCompareEqualTo) { char cType[(CFStringGetLength(type) * 4) + 1]; CFStringGetCString(type, cType, sizeof(cType), kCFStringEncodingUTF8); CFStringRef bsdName = SCNetworkInterfaceGetBSDName(iface); char cBsdName[(CFStringGetLength(bsdName) * 4) + 1]; CFStringGetCString(bsdName, cBsdName, sizeof(cBsdName), kCFStringEncodingUTF8); InterfaceInfo info((string(cBsdName)), (string(cServiceName)), (string(cType))); result.push_back(info); } } } CFRelease(services); CFRelease(set); CFRelease(prefs); return result; }
STATIC SCNetworkInterfaceRef copy_configured_interface(SCPreferencesRef prefs, CFStringRef if_name) { SCNetworkSetRef current_set = NULL; int count; int i; SCNetworkInterfaceRef ret_if = NULL; CFArrayRef services = NULL; current_set = SCNetworkSetCopyCurrent(prefs); if (current_set == NULL) { goto done; } services = SCNetworkSetCopyServices(current_set); if (services == NULL) { goto done; } count = CFArrayGetCount(services); for (i = 0; i < count; i++) { CFStringRef this_if_name; SCNetworkInterfaceRef this_if; SCNetworkServiceRef s; s = (SCNetworkServiceRef)CFArrayGetValueAtIndex(services, i); this_if = SCNetworkServiceGetInterface(s); if (this_if == NULL) { continue; } this_if_name = SCNetworkInterfaceGetBSDName(this_if); if (this_if_name == NULL) { continue; } if (CFEqual(this_if_name, if_name)) { ret_if = this_if; CFRetain(ret_if); break; } } done: my_CFRelease(¤t_set); my_CFRelease(&services); return (ret_if); }
static CFArrayRef copyServices(SCNetworkSetRef set) { CFArrayRef services; SCNetworkSetPrivateRef setPrivate = (SCNetworkSetPrivateRef)set; // first, assume that we only want to add new services // for those interfaces that are not represented in the // current set. services = SCNetworkSetCopyServices(set); if ((services != NULL) && setPrivate->established) { // but, if we are given an existing (or "established") set // than we only want to add new services for those interfaces // that are not represented in *any* set. CFRelease(services); services = SCNetworkServiceCopyAll(setPrivate->prefs); } return services; }
Boolean SCNetworkSetAddService(SCNetworkSetRef set, SCNetworkServiceRef service) { SCNetworkInterfaceRef interface; CFArrayRef interface_config = NULL; CFStringRef link; Boolean ok; CFStringRef path; SCNetworkServicePrivateRef servicePrivate = (SCNetworkServicePrivateRef)service; SCNetworkSetPrivateRef setPrivate = (SCNetworkSetPrivateRef)set; if (!isA_SCNetworkSet(set)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } if (!isA_SCNetworkService(service) || (servicePrivate->prefs == NULL)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } // make sure that we do not add an orphaned network service if its // associated interface is a member of a bond or bridge. interface = SCNetworkServiceGetInterface(service); if ((interface != NULL) && __SCNetworkInterfaceIsMember(servicePrivate->prefs, interface)) { _SCErrorSet(kSCStatusKeyExists); return FALSE; } //#define PREVENT_DUPLICATE_SETS #ifdef PREVENT_DUPLICATE_SETS CFArrayRef sets; // ensure that each service is only a member of ONE set sets = SCNetworkSetCopyAll(setPrivate->prefs); if (sets != NULL) { CFIndex i; CFIndex n; n = CFArrayGetCount(sets); for (i = 0; i < n; i++) { Boolean found; CFArrayRef services; SCNetworkSetRef set; set = CFArrayGetValueAtIndex(sets, i); services = SCNetworkSetCopyServices(set); found = CFArrayContainsValue(services, CFRangeMake(0, CFArrayGetCount(services)), service); CFRelease(services); if (found) { CFRelease(sets); _SCErrorSet(kSCStatusKeyExists); return FALSE; } } CFRelease(sets); } #endif /* PREVENT_DUPLICATE_SETS */ // get the [deep] interface configuration settings interface = SCNetworkServiceGetInterface(service); if (interface != NULL) { interface_config = __SCNetworkInterfaceCopyDeepConfiguration(set, interface); } // create the link between "set" and the "service" path = SCPreferencesPathKeyCreateSetNetworkServiceEntity(NULL, // allocator setPrivate->setID, // set servicePrivate->serviceID, // service NULL); // entity link = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL, // allocator servicePrivate->serviceID, // service NULL); // entity ok = SCPreferencesPathSetLink(setPrivate->prefs, path, link); #ifdef PREVENT_DUPLICATE_SERVICE_NAMES if (ok) { ok = ensure_unique_service_name(service); if (!ok) { // if we could not ensure a unique name, remove the (just added) // link between the "set" and the "service" (void) SCPreferencesPathRemoveValue(setPrivate->prefs, path); } } #endif // PREVENT_DUPLICATE_SERVICE_NAMES CFRelease(path); CFRelease(link); if (!ok) { goto done; } // push the [deep] interface configuration into all sets which contain this service. if (interface != NULL) { __SCNetworkInterfaceSetDeepConfiguration(set, interface, interface_config); } // add service to ServiceOrder _serviceOrder_add(set, service); // mark set as no longer "new" setPrivate->established = TRUE; done : if (interface_config != NULL) CFRelease(interface_config); return ok; }
SCNetworkServiceRef SCNetworkSetCopySelectedVPNService(SCNetworkSetRef set) { CFIndex i; CFIndex n; SCNetworkServiceRef selected = NULL; CFArrayRef services; CFMutableArrayRef services_vpn = NULL; if (!isA_SCNetworkSet(set)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; } services = SCNetworkSetCopyServices(set); if (services != NULL) { n = CFArrayGetCount(services); for (i = 0; i < n; i++) { SCNetworkServiceRef service; service = CFArrayGetValueAtIndex(services, i); if (!SCNetworkServiceGetEnabled(service)) { // if not enabled continue; } if (!_SCNetworkServiceIsVPN(service)) { // if not VPN service continue; } if (services_vpn == NULL) { services_vpn = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); } CFArrayAppendValue(services_vpn, service); } CFRelease(services); } if (services_vpn == NULL) { // if no VPN services return NULL; } n = CFArrayGetCount(services_vpn); if (n > 1) { CFArrayRef order; CFMutableArrayRef sorted; order = SCNetworkSetGetServiceOrder(set); sorted = CFArrayCreateMutableCopy(NULL, 0, services_vpn); CFArraySortValues(sorted, CFRangeMake(0, CFArrayGetCount(sorted)), _SCNetworkServiceCompare, (void *)order); CFRelease(services_vpn); services_vpn = sorted; } #if TARGET_OS_IPHONE if (n > 1) { CFStringRef serviceID_prefs; #define VPN_PREFERENCES CFSTR("com.apple.mobilevpn") #define VPN_SERVICE_ID CFSTR("activeVPNID") CFPreferencesAppSynchronize(VPN_PREFERENCES); serviceID_prefs = CFPreferencesCopyAppValue(VPN_SERVICE_ID, VPN_PREFERENCES); if (serviceID_prefs != NULL) { for (i = 0; i < n; i++) { SCNetworkServiceRef service; CFStringRef serviceID; service = CFArrayGetValueAtIndex(services_vpn, i); serviceID = SCNetworkServiceGetServiceID(service); if (CFEqual(serviceID, serviceID_prefs)) { selected = service; CFRetain(selected); break; } } CFRelease(serviceID_prefs); } } #endif // TARGET_OS_IPHONE if (selected == NULL) { selected = CFArrayGetValueAtIndex(services_vpn, 0); CFRetain(selected); } CFRelease(services_vpn); return selected; }
static Boolean __SCNetworkSetEstablishDefaultConfigurationForInterfaces(SCNetworkSetRef set, CFArrayRef interfaces, Boolean excludeHidden) { CFSetRef excluded = NULL; CFIndex i; CFIndex n = 0; Boolean ok = TRUE; CFArrayRef services; SCNetworkSetPrivateRef setPrivate = (SCNetworkSetPrivateRef)set; Boolean updated = FALSE; Boolean updatedIFs = FALSE; #if TARGET_OS_IPHONE CFArrayRef orphans = NULL; CFArrayRef sets; sets = SCNetworkSetCopyAll(setPrivate->prefs); if (sets != NULL) { if (CFArrayGetCount(sets) == 1) { services = SCNetworkSetCopyServices(set); if (services != NULL) { n = CFArrayGetCount(services); CFRelease(services); } if ((n == 0) && CFEqual(set, CFArrayGetValueAtIndex(sets, 0))) { // after a "Reset Network Settings" we need to find (and // add back) any VPN services that were orphaned. orphans = SCNetworkServiceCopyAll(setPrivate->prefs); } } CFRelease(sets); } #endif // TARGET_OS_IPHONE // copy network services services = copyServices(set); // copy network interfaces to be excluded excluded = copyExcludedInterfaces(setPrivate->prefs); #if !TARGET_OS_IPHONE // look for interfaces that should auto-magically be added // to an Ethernet bridge n = (interfaces != NULL) ? CFArrayGetCount(interfaces) : 0; for (i = 0; i < n; i++) { SCBridgeInterfaceRef bridge = NULL; SCNetworkInterfaceRef interface; interface = CFArrayGetValueAtIndex(interfaces, i); if (excludeHidden && skipInterface(interface)) { // if not auto-configure continue; } if ((excluded != NULL) && CFSetContainsValue(excluded, interface)) { // if this interface is a member of a Bond or Bridge continue; } if (__SCNetworkServiceExistsForInterface(services, interface)) { // if this is not a new interface continue; } if (_SCNetworkInterfaceIsBuiltin(interface) && _SCNetworkInterfaceIsThunderbolt(interface) && !isA_SCBridgeInterface(interface)) { // add built-in Thunderbolt interfaces to bridge bridge = copyAutoBridgeInterface(setPrivate->prefs, CFSTR("thunderbolt-bridge")); } if (bridge != NULL) { CFIndex bridgeIndex; CFArrayRef members; CFMutableArrayRef newMembers; CFMutableSetRef newExcluded; CFMutableArrayRef newInterfaces; CFArrayRef newServices; // track the bridge interface (if it's in our list) bridgeIndex = CFArrayGetFirstIndexOfValue(interfaces, CFRangeMake(0, CFArrayGetCount(interfaces)), bridge); // add new member interface members = SCBridgeInterfaceGetMemberInterfaces(bridge); if ((members != NULL) && (CFArrayGetCount(members) > 0)) { newMembers = CFArrayCreateMutableCopy(NULL, 0, members); updated = TRUE; // if we're updating an existing bridge } else { newMembers = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); } CFArrayAppendValue(newMembers, interface); ok = SCBridgeInterfaceSetMemberInterfaces(bridge, newMembers); CFRelease(newMembers); if (!ok) { SC_log(LOG_INFO, "could not update bridge with \"%@\": %s", SCNetworkInterfaceGetLocalizedDisplayName(interface), SCErrorString(SCError())); CFRelease(bridge); continue; } // exclude the new member interface newExcluded = CFSetCreateMutableCopy(NULL, 0, excluded); CFRelease(excluded); CFSetAddValue(newExcluded, interface); excluded = newExcluded; // update the list of interfaces to include the [new or updated] bridge newInterfaces = CFArrayCreateMutableCopy(NULL, 0, interfaces); if (bridgeIndex != kCFNotFound) { CFArraySetValueAtIndex(newInterfaces, bridgeIndex, bridge); } else { CFArrayAppendValue(newInterfaces, bridge); } if (updatedIFs) { CFRelease(interfaces); } interfaces = newInterfaces; updatedIFs = TRUE; // refresh [existing] services newServices = updateServices(services, bridge); if (newServices != NULL) { CFRelease(services); services = newServices; } CFRelease(bridge); } } #endif // !TARGET_OS_IPHONE n = (interfaces != NULL) ? CFArrayGetCount(interfaces) : 0; for (i = 0; i < n; i++) { SCNetworkInterfaceRef interface; CFMutableArrayRef interface_list; interface = CFArrayGetValueAtIndex(interfaces, i); if (excludeHidden && skipInterface(interface)) { // if not auto-configure continue; } if ((excluded != NULL) && CFSetContainsValue(excluded, interface)) { // if this interface is a member of a Bond or Bridge continue; } if (__SCNetworkServiceExistsForInterface(services, interface)) { // if this is not a new interface continue; } interface_list = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); CFArrayAppendValue(interface_list, interface); while (ok && (CFArrayGetCount(interface_list) > 0)) { CFArrayRef protocol_types; interface = CFArrayGetValueAtIndex(interface_list, 0); protocol_types = SCNetworkInterfaceGetSupportedProtocolTypes(interface); if ((protocol_types != NULL) && (CFArrayGetCount(protocol_types) > 0)) { SCNetworkServiceRef service; service = SCNetworkServiceCreate(setPrivate->prefs, interface); if (service == NULL) { SC_log(LOG_INFO, "could not create service for \"%@\": %s", SCNetworkInterfaceGetLocalizedDisplayName(interface), SCErrorString(SCError())); ok = FALSE; goto nextInterface; } ok = SCNetworkServiceEstablishDefaultConfiguration(service); if (!ok) { SC_log(LOG_INFO, "could not estabish default configuration for \"%@\": %s", SCNetworkInterfaceGetLocalizedDisplayName(interface), SCErrorString(SCError())); SCNetworkServiceRemove(service); CFRelease(service); goto nextInterface; } ok = SCNetworkSetAddService(set, service); if (!ok) { SC_log(LOG_INFO, "could not add service for \"%@\": %s", SCNetworkInterfaceGetLocalizedDisplayName(interface), SCErrorString(SCError())); SCNetworkServiceRemove(service); CFRelease(service); goto nextInterface; } CFRelease(service); updated = TRUE; } else { add_supported_interfaces(interface_list, interface); } nextInterface : CFArrayRemoveValueAtIndex(interface_list, 0); } CFRelease(interface_list); } if (updatedIFs) CFRelease(interfaces); if (services != NULL) CFRelease(services); if (excluded != NULL) CFRelease(excluded); #if TARGET_OS_IPHONE if (orphans != NULL) { if (ok && updated) { CFIndex i; CFIndex n = CFArrayGetCount(orphans); for (i = 0; i < n; i++) { SCNetworkServiceRef service; service = CFArrayGetValueAtIndex(orphans, i); if (_SCNetworkServiceIsVPN(service)) { ok = SCNetworkSetAddService(set, service); if (!ok) { break; } } } } CFRelease(orphans); } #endif // TARGET_OS_IPHONE if (ok && !updated) { // if no changes were made _SCErrorSet(kSCStatusOK); } return updated; }
__private_extern__ void show_services(int argc, char **argv) { CFIndex i; CFIndex n; if (prefs == NULL) { SCPrint(TRUE, stdout, CFSTR("network configuration not open\n")); return; } if (argc == 1) { if (services != NULL) CFRelease(services); services = SCNetworkServiceCopyAll(prefs); } else { if (net_set == NULL) { SCPrint(TRUE, stdout, CFSTR("set not selected\n")); return; } if (services != NULL) CFRelease(services); services = SCNetworkSetCopyServices(net_set); n = (services != NULL) ? CFArrayGetCount(services) : 0; if (n > 1) { CFArrayRef order; CFMutableArrayRef sorted; order = SCNetworkSetGetServiceOrder(net_set); sorted = CFArrayCreateMutableCopy(NULL, 0, services); CFArraySortValues(sorted, CFRangeMake(0, CFArrayGetCount(sorted)), _SCNetworkServiceCompare, (void *)order); CFRelease(services); services = sorted; } } if (services == NULL) { SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError())); return; } n = CFArrayGetCount(services); for (i = 0; i < n; i++) { SCNetworkServiceRef service; CFStringRef serviceName; CFStringRef serviceID; service = CFArrayGetValueAtIndex(services, i); serviceID = SCNetworkServiceGetServiceID(service); serviceName = SCNetworkServiceGetName(service); if (serviceName == NULL) serviceName = CFSTR(""); SCPrint(TRUE, stdout, CFSTR("%c%2ld: %@%-*s (%@)%s\n"), ((net_service != NULL) && CFEqual(service, net_service)) ? '>' : ' ', i + 1, serviceName, (int)(30 - CFStringGetLength(serviceName)), " ", serviceID, SCNetworkServiceGetEnabled(service) ? "" : " *DISABLED*"); __show_service_interface(service, " Interface : "); __show_service_protocols(service, " ", TRUE); } return; }
__private_extern__ void set_service(int argc, char **argv) { Boolean ok; if (net_service == NULL) { SCPrint(TRUE, stdout, CFSTR("service not selected\n")); return; } if (argc < 1) { SCPrint(TRUE, stdout, CFSTR("set what?\n")); return; } while (argc > 0) { char *command; command = argv[0]; argv++; argc--; if (strcmp(command, "name") == 0) { CFStringRef serviceName; if (argc < 1) { SCPrint(TRUE, stdout, CFSTR("name not specified\n")); return; } serviceName = (strlen(argv[0]) > 0) ? CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8) : NULL; argv++; argc--; ok = SCNetworkServiceSetName(net_service, serviceName); if (serviceName != NULL) CFRelease(serviceName); if (!ok) { SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError())); return; } _prefs_changed = TRUE; } else if (strcmp(command, "order") == 0) { char *end; long newIndex; CFIndex nServices; char *str; CFArrayRef services; services = SCNetworkSetCopyServices(net_set); nServices = CFArrayGetCount(services); CFRelease(services); if (argc < 1) { SCPrint(TRUE, stdout, CFSTR("order not specified\n")); return; } if (net_set == NULL) { SCPrint(TRUE, stdout, CFSTR("set not selected\n")); return; } str = argv[0]; argv++; argc--; errno = 0; newIndex = strtol(str, &end, 10); if ((*str != '\0') && (*end == '\0') && (errno == 0)) { if ((newIndex > 0) && (newIndex <= nServices)) { CFIndex curIndex; CFMutableArrayRef newOrder; CFArrayRef order; CFStringRef serviceID = SCNetworkServiceGetServiceID(net_service); order = SCNetworkSetGetServiceOrder(net_set); if (order == NULL) { newOrder = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); } else { newOrder = CFArrayCreateMutableCopy(NULL, 0, order); } curIndex = CFArrayGetFirstIndexOfValue(newOrder, CFRangeMake(0, CFArrayGetCount(newOrder)), serviceID); if (curIndex != kCFNotFound) { CFArrayRemoveValueAtIndex(newOrder, curIndex); } if (newIndex <= CFArrayGetCount(newOrder)) { CFArrayInsertValueAtIndex(newOrder, newIndex - 1, serviceID); } else { CFArrayAppendValue(newOrder, serviceID); } ok = SCNetworkSetSetServiceOrder(net_set, newOrder); CFRelease(newOrder); if (!ok) { SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError())); return; } _prefs_changed = TRUE; } else { SCPrint(TRUE, stdout, CFSTR("set order to what?\n")); return; } } else { SCPrint(TRUE, stdout, CFSTR("set what?\n")); return; } } else if (strcmp(command, "rank") == 0) { SCNetworkServicePrimaryRank rank = kSCNetworkServicePrimaryRankDefault; SCNetworkServiceRef service = (argc < 2) ? net_service : NULL; if (argc < 1) { SCPrint(TRUE, stdout, CFSTR("rank not specified\n")); return; } if (strlen(argv[0]) > 0) { if (strcasecmp(argv[0], "Never") == 0) { rank = kSCNetworkServicePrimaryRankNever; } else if ((service != net_service) && (strcasecmp(argv[0], "First") == 0)) { rank = kSCNetworkServicePrimaryRankFirst; } else if ((service != net_service) && (strcasecmp(argv[0], "Last") == 0)) { rank = kSCNetworkServicePrimaryRankLast; } else if ((service != net_service) && (strcasecmp(argv[0], "Scoped") == 0)) { rank = kSCNetworkServicePrimaryRankScoped; } else { SCPrint(TRUE, stdout, CFSTR("rank not valid\n")); return; } } argv++; argc--; if (service == NULL) { CFStringRef serviceID; SCDynamicStoreRef store; store = SCDynamicStoreCreate(NULL, CFSTR("scutil (set primary rank)"), NULL, NULL); serviceID = SCNetworkServiceGetServiceID(net_service); service = _SCNetworkServiceCopyActive(store, serviceID); CFRelease(store); argv++; argc--; } ok = SCNetworkServiceSetPrimaryRank(service, rank); if (service != net_service) CFRelease(service); if (ok) { if (service == net_service) _prefs_changed = TRUE; } else { SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError())); return; } } else if (strcmp(command, "id") == 0) { CFStringRef serviceID; if ((argc < 1) || (strlen(argv[0]) == 0)) { SCPrint(TRUE, stdout, CFSTR("set id not specified\n")); return; } serviceID = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8); argv++; argc--; ok = _SCNetworkServiceSetServiceID(net_service, serviceID); CFRelease(serviceID); if (!ok) { SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError())); return; } _prefs_changed = TRUE; } else { SCPrint(TRUE, stdout, CFSTR("set what?\n")); } } return; }
static SCNetworkServiceRef _find_service(char *match) { Boolean allowIndex = TRUE; CFIndex i; CFIndex n; CFStringRef select_name = NULL; SCNetworkServiceRef selected = NULL; if (services == NULL) { if (net_set == NULL) { SCPrint(TRUE, stdout, CFSTR("set not selected\n")); return NULL; } services = SCNetworkSetCopyServices(net_set); if (services == NULL) { SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError())); return NULL; } allowIndex = FALSE; } // try to select the service by its serviceID select_name = CFStringCreateWithCString(NULL, match, kCFStringEncodingUTF8); n = CFArrayGetCount(services); for (i = 0; i < n; i++) { SCNetworkServiceRef service; CFStringRef serviceID; service = CFArrayGetValueAtIndex(services, i); serviceID = SCNetworkServiceGetServiceID(service); if (CFEqual(select_name, serviceID)) { selected = service; goto done; } } // try to select the service by its name for (i = 0; i < n; i++) { SCNetworkServiceRef service; CFStringRef serviceName; service = CFArrayGetValueAtIndex(services, i); serviceName = SCNetworkServiceGetName(service); if ((serviceName != NULL) && CFEqual(select_name, serviceName)) { if (selected == NULL) { selected = service; } else { // if multiple services match selected = NULL; SCPrint(TRUE, stdout, CFSTR("multiple services match\n")); goto done; } } } if (selected != NULL) { goto done; } // try to select the service by its name (case insensitive) for (i = 0; i < n; i++) { SCNetworkServiceRef service; CFStringRef serviceName; service = CFArrayGetValueAtIndex(services, i); serviceName = SCNetworkServiceGetName(service); if ((serviceName != NULL) && CFStringCompare(select_name, serviceName, kCFCompareCaseInsensitive) == kCFCompareEqualTo) { if (selected == NULL) { selected = service; } else { // if multiple services match selected = NULL; SCPrint(TRUE, stdout, CFSTR("multiple services match\n")); goto done; } } } if (selected != NULL) { goto done; } // try to select the service by its [BSD] interface name for (i = 0; i < n; i++) { SCNetworkInterfaceRef interface; CFStringRef interfaceName = NULL; SCNetworkServiceRef service; service = CFArrayGetValueAtIndex(services, i); interface = SCNetworkServiceGetInterface(service); while ((interface != NULL) && (interfaceName == NULL)) { interfaceName = SCNetworkInterfaceGetBSDName(interface); if (interfaceName == NULL) { interface = SCNetworkInterfaceGetInterface(interface); } } if (interfaceName == NULL) { continue; } if (CFStringCompare(select_name, interfaceName, kCFCompareCaseInsensitive) == kCFCompareEqualTo) { if (selected == NULL) { selected = service; } else { // if multiple services match selected = NULL; SCPrint(TRUE, stdout, CFSTR("multiple services match\n")); goto done; } } } if (selected != NULL) { goto done; } // try to select the service by its index if (allowIndex) { char *end; char *str = match; long val; errno = 0; val = strtol(str, &end, 10); if ((*str != '\0') && (*end == '\0') && (errno == 0)) { if ((val > 0) && (val <= n)) { selected = CFArrayGetValueAtIndex(services, val - 1); } } } if (selected != NULL) { goto done; } SCPrint(TRUE, stdout, CFSTR("no match, which service?\n")); done : if (select_name != NULL) CFRelease(select_name); return selected; }