Boolean SCVLANInterfaceRemove(SCVLANInterfaceRef vlan) { CFStringRef vlan_if; SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)vlan; Boolean ok; CFStringRef path; if (!isA_SCVLANInterface(vlan)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } if (interfacePrivate->prefs == NULL) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } vlan_if = SCNetworkInterfaceGetBSDName(vlan); path = CFStringCreateWithFormat(NULL, NULL, CFSTR("/%@/%@/%@"), kSCPrefVirtualNetworkInterfaces, kSCNetworkInterfaceTypeVLAN, vlan_if); ok = SCPreferencesPathRemoveValue(interfacePrivate->prefs, path); CFRelease(path); return ok; }
/* * Function: copy_present_interface * Purpose: * Check the list of interfaces on the system, and find the one corresponding * to the specified BSD name. */ STATIC SCNetworkInterfaceRef copy_present_interface(CFStringRef if_name) { int count = 0; int i; CFArrayRef list; SCNetworkInterfaceRef ret = NULL; list = SCNetworkInterfaceCopyAll(); if (list != NULL) { count = CFArrayGetCount(list); } if (count == 0) { goto done; } for (i = 0; i < count; i++) { SCNetworkInterfaceRef this_if; CFStringRef this_if_name; this_if = (SCNetworkInterfaceRef)CFArrayGetValueAtIndex(list, i); this_if_name = SCNetworkInterfaceGetBSDName(this_if); if (this_if_name == NULL) { continue; } if (CFEqual(if_name, this_if_name)) { ret = this_if; CFRetain(ret); break; } } done: my_CFRelease(&list); return (ret); }
/* * 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); }
static CFArrayRef updateServices(CFArrayRef services, SCNetworkInterfaceRef interface) { CFStringRef bsdName; CFIndex i; CFIndex n; CFMutableArrayRef newServices; if (services == NULL) { return NULL; } bsdName = SCNetworkInterfaceGetBSDName(interface); newServices = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); n = CFArrayGetCount(services); for (i = 0; i < n; i++) { SCNetworkInterfaceRef interface; CFStringRef interfaceName; SCNetworkServiceRef newService; SCNetworkServiceRef service; CFStringRef serviceID; SCNetworkServicePrivateRef servicePrivate; service = CFArrayGetValueAtIndex(services, i); interface = SCNetworkServiceGetInterface(service); interfaceName = SCNetworkInterfaceGetBSDName(interface); if (!_SC_CFEqual(interfaceName, bsdName)) { // if not a match, retain CFArrayAppendValue(newServices, service); continue; } // if a match, update serviceID = SCNetworkServiceGetServiceID(service); servicePrivate = (SCNetworkServicePrivateRef)service; newService = SCNetworkServiceCopy(servicePrivate->prefs, serviceID); if (newService != NULL) { CFArrayAppendValue(newServices, newService); CFRelease(newService); } } return newServices; }
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); }
Boolean _SCVLANInterfaceUpdateConfiguration(SCPreferencesRef prefs) { CFArrayRef active = NULL; CFArrayRef config = NULL; CFMutableDictionaryRef devices = NULL; CFIndex i; CFIndex nActive; CFIndex nConfig; Boolean ok = TRUE; int s = -1; if (prefs == NULL) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } /* configured VLANs */ config = SCVLANInterfaceCopyAll(prefs); nConfig = (config != NULL) ? CFArrayGetCount(config) : 0; /* physical interfaces */ devices = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); /* active VLANs */ active = _SCVLANInterfaceCopyActive(); nActive = (active != NULL) ? CFArrayGetCount(active) : 0; /* remove any no-longer-configured VLAN interfaces */ for (i = 0; i < nActive; i++) { SCVLANInterfaceRef a_vlan; CFStringRef a_vlan_if; CFIndex j; Boolean found = FALSE; a_vlan = CFArrayGetValueAtIndex(active, i); a_vlan_if = SCNetworkInterfaceGetBSDName(a_vlan); for (j = 0; j < nConfig; j++) { SCVLANInterfaceRef c_vlan; CFStringRef c_vlan_if; c_vlan = CFArrayGetValueAtIndex(config, j); c_vlan_if = SCNetworkInterfaceGetBSDName(c_vlan); if (CFEqual(a_vlan_if, c_vlan_if)) { found = TRUE; break; } } if (!found) { // remove VLAN interface if (s == -1) { s = inet_dgram_socket(); if (s == -1) { _SCErrorSet(errno); ok = FALSE; goto done; } } if (!__destroyInterface(s, a_vlan_if)) { ok = FALSE; _SCErrorSet(errno); } } } /* create (and update) configured VLAN interfaces */ for (i = 0; i < nConfig; i++) { SCVLANInterfaceRef c_vlan; CFStringRef c_vlan_if; SCNetworkInterfaceRef c_vlan_physical; Boolean found = FALSE; CFIndex j; CFBooleanRef supported; c_vlan = CFArrayGetValueAtIndex(config, i); c_vlan_if = SCNetworkInterfaceGetBSDName(c_vlan); c_vlan_physical = SCVLANInterfaceGetPhysicalInterface(c_vlan); if (c_vlan_physical == NULL) { continue; } // determine if the physical interface supports VLANs supported = CFDictionaryGetValue(devices, c_vlan_physical); if (supported == NULL) { SCNetworkInterfacePrivateRef c_vlan_physicalPrivate = (SCNetworkInterfacePrivateRef)c_vlan_physical; supported = c_vlan_physicalPrivate->supportsVLAN ? kCFBooleanTrue : kCFBooleanFalse; CFDictionaryAddValue(devices, c_vlan_physical, supported); } for (j = 0; j < nActive; j++) { SCVLANInterfaceRef a_vlan; CFStringRef a_vlan_if; a_vlan = CFArrayGetValueAtIndex(active, j); a_vlan_if = SCNetworkInterfaceGetBSDName(a_vlan); if (CFEqual(c_vlan_if, a_vlan_if)) { if (!CFEqual(c_vlan, a_vlan)) { // update VLAN interface if (s == -1) { s = inet_dgram_socket(); if (s == -1) { _SCErrorSet(errno); ok = FALSE; goto done; } } if (!CFBooleanGetValue(supported) || !__vlan_clear(s, c_vlan_if) || !__vlan_set(s, c_vlan_if, SCNetworkInterfaceGetBSDName(c_vlan_physical), SCVLANInterfaceGetTag(c_vlan))) { // something went wrong, try to blow the VLAN away if (!CFBooleanGetValue(supported)) { _SCErrorSet(kSCStatusFailed); } (void)__destroyInterface(s, c_vlan_if); ok = FALSE; } } found = TRUE; break; } } if (!found && CFBooleanGetValue(supported)) { // if the physical interface supports VLANs, add new interface Boolean created; if (s == -1) { s = inet_dgram_socket(); if (s == -1) { _SCErrorSet(errno); ok = FALSE; goto done; } } created = __createInterface(s, c_vlan_if); if (!created || !__vlan_set(s, c_vlan_if, SCNetworkInterfaceGetBSDName(c_vlan_physical), SCVLANInterfaceGetTag(c_vlan))) { if (created) { // something went wrong, try to blow the VLAN away (void)__destroyInterface(s, c_vlan_if); } else { _SCErrorSet(errno); } ok = FALSE; } } } done : if (active) CFRelease(active); if (config) CFRelease(config); if (devices) CFRelease(devices); if (s != -1) (void) close(s); return ok; }
Boolean SCVLANInterfaceSetPhysicalInterfaceAndTag(SCVLANInterfaceRef vlan, SCNetworkInterfaceRef physical, CFNumberRef tag) { SCNetworkInterfacePrivateRef interfacePrivate; Boolean ok = TRUE; if (!isA_SCVLANInterface(vlan)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } if (!isA_SCNetworkInterface(physical)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } interfacePrivate = (SCNetworkInterfacePrivateRef)physical; if (!interfacePrivate->supportsVLAN) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } if (isA_CFNumber(tag)) { int tag_val; CFNumberGetValue(tag, kCFNumberIntType, &tag_val); if ((tag_val < 1) || (tag_val > 4094)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } } else { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } interfacePrivate = (SCNetworkInterfacePrivateRef)vlan; if (interfacePrivate->prefs != NULL) { SCVLANInterfaceRef config_vlan; CFDictionaryRef dict; CFMutableDictionaryRef newDict; CFStringRef path; // make sure that physical interface and tag are not used config_vlan = findVLANInterfaceAndTag(interfacePrivate->prefs, physical, tag); if (config_vlan != NULL) { if (!CFEqual(vlan, config_vlan)) { CFRelease(config_vlan); _SCErrorSet(kSCStatusKeyExists); return FALSE; } CFRelease(config_vlan); } // set interface/tag in the stored preferences path = CFStringCreateWithFormat(NULL, NULL, CFSTR("/%@/%@/%@"), kSCPrefVirtualNetworkInterfaces, kSCNetworkInterfaceTypeVLAN, interfacePrivate->entity_device); dict = SCPreferencesPathGetValue(interfacePrivate->prefs, path); if (!isA_CFDictionary(dict)) { // if the prefs are confused CFRelease(path); _SCErrorSet(kSCStatusFailed); return FALSE; } newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict); CFDictionarySetValue(newDict, kSCPropVirtualNetworkInterfacesVLANInterface, SCNetworkInterfaceGetBSDName(physical)); CFDictionarySetValue(newDict, kSCPropVirtualNetworkInterfacesVLANTag, tag); if (!CFEqual(dict, newDict)) { ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict); } CFRelease(newDict); CFRelease(path); } if (ok) { SCNetworkInterfacePrivateRef newInterface; CFTypeRef save; // set physical interface newInterface = __SCNetworkInterfaceCreateCopy(NULL, physical, interfacePrivate->prefs, interfacePrivate->serviceID); save = interfacePrivate->vlan.interface; interfacePrivate->vlan.interface = (SCNetworkInterfaceRef)newInterface; if (save != NULL) CFRelease(save); // set tag save = interfacePrivate->vlan.tag; interfacePrivate->vlan.tag = CFRetain(tag); if (save != NULL) CFRelease(save); } return ok; }
static Boolean _SCBondInterfaceSetMemberInterfaces(SCBondInterfaceRef bond, CFArrayRef members) { CFIndex i; SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)bond; CFIndex n; CFMutableArrayRef newMembers; Boolean ok = TRUE; n = (members != NULL) ? CFArrayGetCount(members) : 0; // set member interfaces in the stored preferences if (interfacePrivate->prefs != NULL) { CFDictionaryRef dict; CFMutableDictionaryRef newDict; CFStringRef path; path = CFStringCreateWithFormat(NULL, NULL, CFSTR("/%@/%@/%@"), kSCPrefVirtualNetworkInterfaces, kSCNetworkInterfaceTypeBond, interfacePrivate->entity_device); dict = SCPreferencesPathGetValue(interfacePrivate->prefs, path); if (!isA_CFDictionary(dict)) { // if the prefs are confused CFRelease(path); _SCErrorSet(kSCStatusFailed); return FALSE; } newMembers = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); for (i = 0; i < n; i++) { SCNetworkInterfaceRef interface; CFStringRef memberName; interface = CFArrayGetValueAtIndex(members, i); memberName = SCNetworkInterfaceGetBSDName(interface); CFArrayAppendValue(newMembers, memberName); } newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict); CFDictionarySetValue(newDict, kSCPropVirtualNetworkInterfacesBondInterfaces, newMembers); CFRelease(newMembers); if (!CFEqual(dict, newDict)) { ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict); } CFRelease(newDict); CFRelease(path); } if (ok) { newMembers = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); for (i = 0; i < n; i++) { SCNetworkInterfaceRef member; SCNetworkInterfacePrivateRef newMember; member = CFArrayGetValueAtIndex(members, i); newMember = __SCNetworkInterfaceCreateCopy(NULL, member, interfacePrivate->prefs, interfacePrivate->serviceID); CFArrayAppendValue(newMembers, newMember); CFRelease(newMember); } CFRelease(interfacePrivate->bond.interfaces); interfacePrivate->bond.interfaces = newMembers; } return ok; }
Boolean _SCBondInterfaceUpdateConfiguration(SCPreferencesRef prefs) { CFArrayRef active = NULL; CFArrayRef config = NULL; CFIndex i; CFIndex nActive; CFIndex nConfig; Boolean ok = TRUE; int s = -1; if (prefs == NULL) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } /* configured Bonds */ config = SCBondInterfaceCopyAll(prefs); nConfig = (config != NULL) ? CFArrayGetCount(config) : 0; /* active Bonds */ active = _SCBondInterfaceCopyActive(); nActive = (active != NULL) ? CFArrayGetCount(active) : 0; /* * remove any no-longer-configured bond interfaces and * any devices associated with a bond that are no longer * associated with a bond. */ for (i = 0; i < nActive; i++) { SCBondInterfaceRef a_bond; CFStringRef a_bond_if; CFIndex j; Boolean found = FALSE; a_bond = CFArrayGetValueAtIndex(active, i); a_bond_if = SCNetworkInterfaceGetBSDName(a_bond); for (j = 0; j < nConfig; j++) { SCBondInterfaceRef c_bond; CFStringRef c_bond_if; c_bond = CFArrayGetValueAtIndex(config, j); c_bond_if = SCNetworkInterfaceGetBSDName(c_bond); if (CFEqual(a_bond_if, c_bond_if)) { CFIndex a; CFArrayRef a_bond_interfaces; CFIndex a_count; CFArrayRef c_bond_interfaces; CFIndex c_count; c_bond_interfaces = SCBondInterfaceGetMemberInterfaces(c_bond); c_count = (c_bond_interfaces != NULL) ? CFArrayGetCount(c_bond_interfaces) : 0; a_bond_interfaces = SCBondInterfaceGetMemberInterfaces(a_bond); a_count = (a_bond_interfaces != NULL) ? CFArrayGetCount(a_bond_interfaces) : 0; for (a = 0; a < a_count; a++) { SCNetworkInterfaceRef a_interface; CFStringRef a_interface_if; a_interface = CFArrayGetValueAtIndex(a_bond_interfaces, a); if ((c_count == 0) || !CFArrayContainsValue(c_bond_interfaces, CFRangeMake(0, c_count), a_interface)) { /* * if this device is no longer part * of the bond. */ if (s == -1) { s = inet_dgram_socket(); if (s == -1) { _SCErrorSet(errno); ok = FALSE; goto done; } } a_interface_if = SCNetworkInterfaceGetBSDName(a_interface); if (!__bond_remove_interface(s, a_bond_if, a_interface_if)) { ok = FALSE; } } } found = TRUE; break; } } if (!found) { /* * if this interface is no longer configured */ if (s == -1) { s = inet_dgram_socket(); if (s == -1) { _SCErrorSet(errno); ok = FALSE; goto done; } } if (!__destroyInterface(s, a_bond_if)) { _SCErrorSet(errno); ok = FALSE; } } } /* * add any newly-configured bond interfaces and add any * devices that should now be associated with the bond. */ for (i = 0; i < nConfig; i++) { CFNumberRef c_bond_mode; SCBondInterfaceRef c_bond; CFArrayRef c_bond_interfaces; CFStringRef c_bond_if; CFIndex c_count; Boolean found = FALSE; CFIndex j; c_bond = CFArrayGetValueAtIndex(config, i); c_bond_if = SCNetworkInterfaceGetBSDName(c_bond); c_bond_interfaces = SCBondInterfaceGetMemberInterfaces(c_bond); c_bond_mode = SCBondInterfaceGetMode(c_bond); c_count = (c_bond_interfaces != NULL) ? CFArrayGetCount(c_bond_interfaces) : 0; for (j = 0; j < nActive; j++) { SCBondInterfaceRef a_bond; CFArrayRef a_bond_interfaces; CFNumberRef a_bond_mode; CFStringRef a_bond_if; CFIndex a_count; a_bond = CFArrayGetValueAtIndex(active, j); a_bond_if = SCNetworkInterfaceGetBSDName(a_bond); a_bond_interfaces = SCBondInterfaceGetMemberInterfaces(a_bond); a_bond_mode = SCBondInterfaceGetMode(a_bond); a_count = (a_bond_interfaces != NULL) ? CFArrayGetCount(a_bond_interfaces) : 0; if (CFEqual(c_bond_if, a_bond_if)) { CFIndex c; Boolean if_list_change = FALSE; Boolean mode_change = FALSE; found = TRUE; if (!_SC_CFEqual(a_bond_mode, c_bond_mode)) { mode_change = TRUE; } if (!_SC_CFEqual(c_bond_interfaces, a_bond_interfaces)) { if_list_change = TRUE; } if (!mode_change && !if_list_change) { break; // if no change } if (s == -1) { s = inet_dgram_socket(); if (s == -1) { _SCErrorSet(errno); ok = FALSE; goto done; } } if (mode_change) { __bond_set_mode(s, a_bond_if, c_bond_mode); } if (!if_list_change) { break; // no if list changes } /* * ensure that the first device of the bond matches, if * not then we remove all current devices and add them * back in the preferred order. */ if ((c_count > 0) && (a_count > 0) && !CFEqual(CFArrayGetValueAtIndex(c_bond_interfaces, 0), CFArrayGetValueAtIndex(a_bond_interfaces, 0))) { CFIndex a; for (a = 0; a < a_count; a++) { SCNetworkInterfaceRef a_interface; CFStringRef a_interface_if; a_interface = CFArrayGetValueAtIndex(a_bond_interfaces, a); if (!CFArrayContainsValue(c_bond_interfaces, CFRangeMake(0, c_count), a_interface)) { continue; // if already removed } a_interface_if = SCNetworkInterfaceGetBSDName(a_interface); if (!__bond_remove_interface(s, a_bond_if, a_interface_if)) { ok = FALSE; } } a_count = 0; // all active devices have been removed } /* * add any devices which are not currently associated * with the bond interface. */ for (c = 0; c < c_count; c++) { SCNetworkInterfaceRef c_interface; SCNetworkInterfacePrivateRef c_interfacePrivate; CFStringRef c_interface_if; c_interface = CFArrayGetValueAtIndex(c_bond_interfaces, c); if ((a_count == 0) || !CFArrayContainsValue(a_bond_interfaces, CFRangeMake(0, a_count), c_interface)) { /* * check if this member interface can be added to a bond. */ c_interfacePrivate = (SCNetworkInterfacePrivateRef)c_interface; if (!c_interfacePrivate->supportsBond) { // if member not supported continue; } /* * if this member interface is not currently part of the bond. */ c_interface_if = SCNetworkInterfaceGetBSDName(c_interface); if (!__bond_add_interface(s, c_bond_if, c_interface_if)) { // if member could not be added ok = FALSE; } } } break; } } if (!found) { CFIndex c; if (s == -1) { s = inet_dgram_socket(); if (s == -1) { _SCErrorSet(errno); ok = FALSE; goto done; } } /* * establish the new bond interface. */ if (!__createInterface(s, c_bond_if)) { _SCErrorSet(errno); ok = FALSE; continue; } /* set the mode */ __bond_set_mode(s, c_bond_if, c_bond_mode); /* * add the member interfaces */ for (c = 0; c < c_count; c++) { SCNetworkInterfaceRef c_interface; SCNetworkInterfacePrivateRef c_interfacePrivate; CFStringRef c_interface_if; c_interface = CFArrayGetValueAtIndex(c_bond_interfaces, c); c_interfacePrivate = (SCNetworkInterfacePrivateRef)c_interface; if (!c_interfacePrivate->supportsBond) { // if member not supported continue; } c_interface_if = SCNetworkInterfaceGetBSDName(c_interface); if (!__bond_add_interface(s, c_bond_if, c_interface_if)) { // if member could not be added ok = FALSE; } } } } done : if (active != NULL) CFRelease(active); if (config != NULL) CFRelease(config); if (s != -1) (void) close(s); return ok; }
SCBondStatusRef SCBondInterfaceCopyStatus(SCBondInterfaceRef bond) { int bond_if_active; int bond_if_status; CFIndex i; struct if_bond_status_req *ibsr_p = NULL; char if_name[IFNAMSIZ]; CFIndex n; CFNumberRef num; int s; struct if_bond_status *scan_p; SCBondStatusRef status = NULL; CFMutableDictionaryRef status_bond; CFMutableDictionaryRef status_interfaces; if (!isA_SCBondInterface(bond)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; } s = inet_dgram_socket(); if (s == -1) { _SCErrorSet(errno); goto done; } _SC_cfstring_to_cstring(SCNetworkInterfaceGetBSDName(bond), if_name, sizeof(if_name), kCFStringEncodingASCII); if (siocgifmedia(s, if_name, &bond_if_status, &bond_if_active) == -1) { _SCErrorSet(errno); switch (errno) { case EBUSY : case ENXIO : break; default : SCLog(TRUE, LOG_ERR, CFSTR("siocgifmedia(%s) failed: %s"), if_name, strerror(errno)); } goto done; } ibsr_p = if_bond_status_req_copy(s, if_name); if (ibsr_p == NULL) { _SCErrorSet(errno); goto done; } status_bond = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); status_interfaces = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); n = ibsr_p->ibsr_total; for (i = 0, scan_p = (struct if_bond_status *)ibsr_p->ibsr_buffer; i < n; i++, scan_p++) { int collecting = 0; int distributing = 0; SCNetworkInterfaceRef interface; CFStringRef interface_name; struct if_bond_partner_state * ps; CFMutableDictionaryRef status_interface; int status_val; ps = &scan_p->ibs_partner_state; if (lacp_actor_partner_state_in_sync(scan_p->ibs_state)) { /* we're in-sync */ status_val = kSCBondStatusOK; if (lacp_actor_partner_state_in_sync(ps->ibps_state)) { /* partner is also in-sync */ if (lacp_actor_partner_state_collecting(scan_p->ibs_state) && lacp_actor_partner_state_distributing(ps->ibps_state)) { /* we're able to collect (receive) frames */ collecting = 1; } if (lacp_actor_partner_state_distributing(scan_p->ibs_state) && lacp_actor_partner_state_collecting(ps->ibps_state)) { /* we're able to distribute (transmit) frames */ distributing = 1; } } } else { int active = 0; int status = 0; static lacp_system zeroes = { {0, 0, 0, 0, 0, 0}}; if (siocgifmedia(s, scan_p->ibs_if_name, &status, &active) == -1) { switch (errno) { case EBUSY : case ENXIO : break; default : SCLog(TRUE, LOG_ERR, CFSTR("siocgifmedia(%s) failed: %s"), if_name, strerror(errno)); break; } } if (((status & IFM_AVALID) == 0) || ((status & IFM_ACTIVE) == 0) || ((active & IFM_FDX ) == 0)) { /* link down or not full-duplex */ status_val = kSCBondStatusLinkInvalid; } else if ((ps->ibps_system_priority == 0) && (bcmp(&zeroes, &ps->ibps_system, sizeof(zeroes)) == 0)) { /* no one on the other end of the link */ status_val = kSCBondStatusNoPartner; } else if (active != bond_if_active) { /* the link speed was different */ status_val = kSCBondStatusLinkInvalid; } else { /* partner is not in the active group */ status_val = kSCBondStatusNotInActiveGroup; } } // interface strlcpy(if_name, scan_p->ibs_if_name, sizeof(if_name)); interface_name = CFStringCreateWithCString(NULL, if_name, kCFStringEncodingASCII); interface = _SCNetworkInterfaceCreateWithBSDName(NULL, interface_name, kIncludeNoVirtualInterfaces); CFRelease(interface_name); // interface status status_interface = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); num = CFNumberCreate(NULL, kCFNumberIntType, &status_val); CFDictionarySetValue(status_interface, kSCBondStatusDeviceAggregationStatus, num); CFRelease(num); num = CFNumberCreate(NULL, kCFNumberIntType, &collecting); CFDictionarySetValue(status_interface, kSCBondStatusDeviceCollecting, num); CFRelease(num); num = CFNumberCreate(NULL, kCFNumberIntType, &distributing); CFDictionarySetValue(status_interface, kSCBondStatusDeviceDistributing, num); CFRelease(num); CFDictionarySetValue(status_interfaces, interface, status_interface); CFRelease(interface); CFRelease(status_interface); } status = __SCBondStatusCreatePrivate(NULL, bond, status_bond, status_interfaces); CFRelease(status_bond); CFRelease(status_interfaces); done: if (s != -1) { close(s); } if (ibsr_p != NULL) { free(ibsr_p); } return (SCBondStatusRef)status; }
/* * Function: saveInterfaceEAPOLConfiguration * Purpose: * Save the SCNetworkInterface EAPOL information for System and LoginWindow * modes. * * Iterate over the changed SCNetworkInterfaceRef list cfg->sc_changed_if, * and for each interface, grab the EAPOL extended information from * cfg->sc_prefs. Then set the corresponding value in the new * freshly created SCPreferencesRef. * * All this done to avoid a writer getting Stale Object errors * when it has its own SCPreferencesRef object that it manipulates while * having an EAPOLClientConfigurationRef open. */ STATIC Boolean saveInterfaceEAPOLConfiguration(EAPOLClientConfigurationRef cfg, Boolean * changed_p) { AuthorizationExternalForm * auth_ext_p; int count; int i; SCPreferencesRef prefs = NULL; Boolean ret = FALSE; *changed_p = FALSE; if (cfg->sc_changed_if == NULL) { return (TRUE); } auth_ext_p = EAPOLClientConfigurationGetAuthorizationExternalForm(cfg); if (auth_ext_p != NULL) { AuthorizationRef auth; OSStatus status; status = AuthorizationCreateFromExternalForm(auth_ext_p, &auth); if (status != errAuthorizationSuccess) { EAPLOG(LOG_ERR, "EAPOLClientConfiguration: can't allocate Authorization, %d", (int)status); goto done; } prefs = SCPreferencesCreateWithAuthorization(NULL, kPrefsName, NULL, auth); AuthorizationFree(auth, kAuthorizationFlagDefaults); } else { prefs = SCPreferencesCreate(NULL, kPrefsName, NULL); } count = CFArrayGetCount(cfg->sc_changed_if); for (i = 0; i < count; i++) { CFDictionaryRef dict; CFStringRef if_name; SCNetworkInterfaceRef net_if; net_if = (SCNetworkInterfaceRef) CFArrayGetValueAtIndex(cfg->sc_changed_if, i); if_name = SCNetworkInterfaceGetBSDName(net_if); if (if_name == NULL) { /* should not happen */ EAPLOG(LOG_ERR, "EAPOLClientConfiguration: missing BSD name"); continue; } dict = SCNetworkInterfaceGetExtendedConfiguration(net_if, kEAPOL); /* find the same interface in the saving prefs */ if (set_eapol_configuration(prefs, if_name, dict) == FALSE) { continue; } } ret = SCPreferencesCommitChanges(prefs); if (ret == FALSE) { EAPLOG(LOG_NOTICE, "EAPOLClientConfigurationSave SCPreferencesCommitChanges" " failed %s", SCErrorString(SCError())); goto done; } SCPreferencesApplyChanges(prefs); *changed_p = TRUE; done: my_CFRelease(&cfg->sc_changed_if); my_CFRelease(&prefs); return (ret); }
__private_extern__ void select_service(int argc, char **argv) { SCNetworkInterfaceRef interface; SCNetworkServiceRef service; CFStringRef serviceName; service = _find_service(argv[0]); if (service == NULL) { return; } if (net_service != NULL) CFRelease(net_service); net_service = CFRetain(service); serviceName = SCNetworkServiceGetName(service); if (serviceName != NULL) { SCPrint(TRUE, stdout, CFSTR("service \"%@\" selected\n"), serviceName); } else { SCPrint(TRUE, stdout, CFSTR("service ID \"%@\" selected\n"), SCNetworkServiceGetServiceID(service)); } interface = SCNetworkServiceGetInterface(service); if (interface != NULL) { CFStringRef interfaceName; if (net_interface != NULL) CFRelease(net_interface); net_interface = CFRetain(interface); interfaceName = SCNetworkInterfaceGetLocalizedDisplayName(interface); if (interfaceName == NULL) { interfaceName = SCNetworkInterfaceGetBSDName(interface); } if (interfaceName == NULL) { interfaceName = SCNetworkInterfaceGetInterfaceType(interface); } SCPrint(TRUE, stdout, CFSTR("& interface \"%@\" selected\n"), interfaceName); } else { if (net_interface != NULL) { CFRelease(net_interface); net_interface = NULL; SCPrint(TRUE, stdout, CFSTR("& no interface selected\n")); } } if (protocols != NULL) { CFRelease(protocols); protocols = NULL; } if (net_protocol != NULL) { CFRelease(net_protocol); net_protocol = NULL; SCPrint(TRUE, stdout, CFSTR("& no protocol selected\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; }
__private_extern__ void create_service(int argc, char **argv) { SCNetworkInterfaceRef interface; CFStringRef interfaceName; Boolean ok; SCNetworkServiceRef service = NULL; CFStringRef serviceName; CFStringRef setName; CFArrayRef supported; if (prefs == NULL) { SCPrint(TRUE, stdout, CFSTR("network configuration not open\n")); return; } if (net_set == NULL) { SCPrint(TRUE, stdout, CFSTR("set not selected\n")); return; } if (argc < 1) { if (net_interface == NULL) { SCPrint(TRUE, stdout, CFSTR("no network interface selected\n")); return; } interface = net_interface; } else { int nArgs; interface = _find_interface(argc, argv, &nArgs); argv += nArgs; argc -= nArgs; } if (interface == NULL) { return; } supported = SCNetworkInterfaceGetSupportedProtocolTypes(interface); if (supported == NULL) { SCPrint(TRUE, stdout, CFSTR("no network protocols are supported over this interface\n")); return; } service = SCNetworkServiceCreate(prefs, interface); if (service == NULL) { SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError())); goto done; } if ((argc > 0) && (strlen(argv[0]) > 0)) { Boolean ok; serviceName = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8); // argv++; // argc--; ok = SCNetworkServiceSetName(service, serviceName); CFRelease(serviceName); if (!ok) { SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError())); (void)SCNetworkServiceRemove(service); goto done; } } ok = SCNetworkServiceEstablishDefaultConfiguration(service); if (!ok) { SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError())); (void)SCNetworkServiceRemove(service); goto done; } ok = SCNetworkSetAddService(net_set, service); if (!ok) { SCPrint(TRUE, stdout, CFSTR("service not created: %s\n"), SCErrorString(SCError())); (void)SCNetworkServiceRemove(service); goto done; } _prefs_changed = TRUE; if (net_service != NULL) CFRelease(net_service); net_service = CFRetain(service); serviceName = SCNetworkServiceGetName(service); if (serviceName != NULL) { SCPrint(TRUE, stdout, CFSTR("service \"%@\" (%@) created and selected\n"), serviceName, SCNetworkServiceGetServiceID(service)); } else { SCPrint(TRUE, stdout, CFSTR("service ID \"%@\" created and selected\n"), SCNetworkServiceGetServiceID(service)); } setName = SCNetworkSetGetName(net_set); if (setName != NULL) { SCPrint(TRUE, stdout, CFSTR("& added to set \"%@\"\n"), setName); } else { SCPrint(TRUE, stdout, CFSTR("& added to set ID \"%@\"\n"), SCNetworkSetGetSetID(net_set)); } if (net_interface != NULL) CFRelease(net_interface); net_interface = SCNetworkServiceGetInterface(net_service); if (net_interface != NULL) { CFRetain(net_interface); } interfaceName = SCNetworkInterfaceGetLocalizedDisplayName(interface); if (interfaceName == NULL) { interfaceName = SCNetworkInterfaceGetBSDName(interface); } if (interfaceName == NULL) { interfaceName = SCNetworkInterfaceGetInterfaceType(interface); } SCPrint(TRUE, stdout, CFSTR("& interface \"%@\" selected\n"), interfaceName); if (protocols != NULL) { CFRelease(protocols); protocols = NULL; } if (net_protocol != NULL) { CFRelease(net_protocol); net_protocol = NULL; SCPrint(TRUE, stdout, CFSTR("& no protocol selected\n")); } if (services != NULL) { CFRelease(services); services = NULL; } done : if (service != NULL) CFRelease(service); return; }