Boolean SCNetworkSetEstablishDefaultInterfaceConfiguration(SCNetworkSetRef set, SCNetworkInterfaceRef interface) { CFArrayRef interfaces; Boolean updated; if (!isA_SCNetworkSet(set)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } if (!isA_SCNetworkInterface(interface)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } interfaces = CFArrayCreate(NULL, (const void **)&interface, 1, &kCFTypeArrayCallBacks); assert(interfaces != NULL); updated = __SCNetworkSetEstablishDefaultConfigurationForInterfaces(set, interfaces, FALSE); CFRelease(interfaces); return updated; }
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; }
SCVLANInterfaceRef SCVLANInterfaceCreate(SCPreferencesRef prefs, SCNetworkInterfaceRef physical, CFNumberRef tag) { CFAllocatorRef allocator; CFIndex i; SCNetworkInterfacePrivateRef interfacePrivate; SCVLANInterfaceRef vlan; if (prefs == NULL) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; } if (!isA_SCNetworkInterface(physical)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; } interfacePrivate = (SCNetworkInterfacePrivateRef)physical; if (!interfacePrivate->supportsVLAN) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; } if (isA_CFNumber(tag)) { int tag_val; CFNumberGetValue(tag, kCFNumberIntType, &tag_val); if ((tag_val < 1) || (tag_val > 4094)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; } } else { _SCErrorSet(kSCStatusInvalidArgument); return NULL; } // make sure that physical interface and tag are not used vlan = findVLANInterfaceAndTag(prefs, physical, tag); if (vlan != NULL) { CFRelease(vlan); _SCErrorSet(kSCStatusKeyExists); return NULL; } allocator = CFGetAllocator(prefs); // create a new VLAN using an unused interface name for (i = 0; vlan == NULL; i++) { CFDictionaryRef dict; CFStringRef vlan_if; Boolean ok; CFStringRef path; vlan_if = CFStringCreateWithFormat(allocator, NULL, CFSTR("vlan%ld"), i); path = CFStringCreateWithFormat(allocator, NULL, CFSTR("/%@/%@/%@"), kSCPrefVirtualNetworkInterfaces, kSCNetworkInterfaceTypeVLAN, vlan_if); dict = SCPreferencesPathGetValue(prefs, path); if (dict != NULL) { // if VLAN interface name not available CFRelease(path); CFRelease(vlan_if); continue; } // add the VLAN to the stored preferences dict = CFDictionaryCreate(allocator, NULL, NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); ok = SCPreferencesPathSetValue(prefs, path, dict); CFRelease(dict); CFRelease(path); if (!ok) { // if the VLAN could not be saved CFRelease(vlan_if); _SCErrorSet(kSCStatusFailed); break; } // create the SCVLANInterfaceRef vlan = (SCVLANInterfaceRef)_SCVLANInterfaceCreatePrivate(allocator, vlan_if); CFRelease(vlan_if); // estabish link to the stored configuration interfacePrivate = (SCNetworkInterfacePrivateRef)vlan; interfacePrivate->prefs = CFRetain(prefs); // set physical interface and tag SCVLANInterfaceSetPhysicalInterfaceAndTag(vlan, physical, tag); } return vlan; }