Exemple #1
0
static CFSetRef	/* of SCNetworkInterfaceRef's */
copyExcludedInterfaces(SCPreferencesRef prefs)
{
	CFMutableSetRef	excluded;
	CFArrayRef	interfaces;

	excluded = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);

#if	!TARGET_OS_IPHONE
	// exclude Bond [member] interfaces
	interfaces = SCBondInterfaceCopyAll(prefs);
	if (interfaces != NULL) {
		__SCBondInterfaceListCollectMembers(interfaces, excluded);
		CFRelease(interfaces);
	}
#endif	// !TARGET_OS_IPHONE

	// exclude Bridge [member] interfaces
	interfaces = SCBridgeInterfaceCopyAll(prefs);
	if (interfaces != NULL) {
		__SCBridgeInterfaceListCollectMembers(interfaces, excluded);
		CFRelease(interfaces);
	}

	return excluded;
}
CFArrayRef
SCVLANInterfaceCopyAvailablePhysicalInterfaces()
{
	CFMutableArrayRef	available;
	CFArrayRef		bond_interfaces		= NULL;
	CFArrayRef		bridge_interfaces	= NULL;
	CFMutableSetRef		excluded		= NULL;
	CFArrayRef		interfaces;
	SCPreferencesRef	prefs;

	available = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);

	prefs = SCPreferencesCreate(NULL, CFSTR("SCVLANInterfaceCopyAvailablePhysicalInterfaces"), NULL);
	if (prefs != NULL) {
#if	!TARGET_OS_IPHONE
		bond_interfaces = SCBondInterfaceCopyAll(prefs);
		if (bond_interfaces != NULL) {
			excluded = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
			__SCBondInterfaceListCollectMembers(bond_interfaces, excluded);
		}
#endif	// !TARGET_OS_IPHONE

		bridge_interfaces = SCBridgeInterfaceCopyAll(prefs);
		if (bridge_interfaces != NULL) {
			if (excluded == NULL) {
				excluded = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
			}
			__SCBridgeInterfaceListCollectMembers(bridge_interfaces, excluded);
		}

		CFRelease(prefs);
	}

	// add real interfaces that aren't part of a bond or bridge
	interfaces = __SCNetworkInterfaceCopyAll_IONetworkInterface();
	if (interfaces != NULL) {
		addAvailableInterfaces(available, interfaces, excluded);
		CFRelease(interfaces);
	}

	// add bond interfaces
	if (bond_interfaces != NULL) {
		addAvailableInterfaces(available, bond_interfaces, NULL);
		CFRelease(bond_interfaces);
	}

	// add bridge interfaces
	if (bridge_interfaces != NULL) {
		addAvailableInterfaces(available, bridge_interfaces, NULL);
		CFRelease(bridge_interfaces);
	}

	if (excluded != NULL) {
		CFRelease(excluded);
	}

	return available;
}
Exemple #3
0
CFArrayRef /* of SCNetworkInterfaceRef's */
SCNetworkSetCopyAvailableInterfaces(SCNetworkSetRef set)
{
	CFMutableArrayRef	available;
	CFMutableSetRef		excluded	= NULL;
	int			i;
	CFArrayRef		interfaces;
	CFIndex			n_interfaces;
	CFIndex			n_exclusions	= 0;
	SCPreferencesRef	prefs;
	SCNetworkSetPrivateRef	setPrivate;

	setPrivate = (SCNetworkSetPrivateRef)set;
	prefs = setPrivate->prefs;

	interfaces = _SCNetworkInterfaceCopyAllWithPreferences(prefs);
	n_interfaces = CFArrayGetCount(interfaces);
	if (n_interfaces == 0) {
		return interfaces;
	}

	if (prefs != NULL) {
		CFArrayRef	bridges	= NULL;

		excluded = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);

#if	!TARGET_OS_IPHONE
		CFArrayRef	bonds	= NULL;

		bonds = SCBondInterfaceCopyAll(prefs);
		if (bonds != NULL) {
			__SCBondInterfaceListCollectMembers(bonds, excluded);
			CFRelease(bonds);
		}
#endif	/* !TARGET_OS_IPHONE */

		bridges = SCBridgeInterfaceCopyAll(prefs);
		if (bridges != NULL) {
			__SCBridgeInterfaceListCollectMembers(bridges, excluded);
			CFRelease(bridges);
		}

		n_exclusions = CFSetGetCount(excluded);
	}

	if (n_exclusions == 0) {
		if (excluded != NULL) {
			CFRelease(excluded);
		}

		return interfaces;
	}

	available = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);

	for (i = 0; i < n_interfaces; i++) {
		SCNetworkInterfaceRef	interface;

		interface = CFArrayGetValueAtIndex(interfaces, i);
		if (CFSetContainsValue(excluded, interface)) {
			// if excluded
			continue;
		}

		CFArrayAppendValue(available, interface);
	}

	CFRelease(interfaces);
	CFRelease(excluded);

	return available;
}
CFArrayRef /* of SCNetworkInterfaceRef's */
SCBondInterfaceCopyAvailableMemberInterfaces(SCPreferencesRef prefs)
{
	CFMutableArrayRef	available;
	CFMutableSetRef		excluded;
	CFArrayRef		interfaces;

	available = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
	excluded  = CFSetCreateMutable  (NULL, 0, &kCFTypeSetCallBacks);

	// exclude Bond [member] interfaces
	interfaces = SCBondInterfaceCopyAll(prefs);
	if (interfaces != NULL) {
		__SCBondInterfaceListCollectMembers(interfaces, excluded);
		CFRelease(interfaces);
	}

	// exclude Bridge [member] interfaces
	interfaces = SCBridgeInterfaceCopyAll(prefs);
	if (interfaces != NULL) {
		__SCBridgeInterfaceListCollectMembers(interfaces, excluded);
		CFRelease(interfaces);
	}

	// exclude VLAN [physical] interfaces
	interfaces = SCVLANInterfaceCopyAll(prefs);
	if (interfaces != NULL) {
		CFIndex	i;
		CFIndex	n;

		n = CFArrayGetCount(interfaces);
		for (i = 0; i < n; i++) {
			SCVLANInterfaceRef	vlanInterface;
			SCNetworkInterfaceRef	physical;

			// exclude the physical interface of this VLAN
			vlanInterface = CFArrayGetValueAtIndex(interfaces, i);
			physical = SCVLANInterfaceGetPhysicalInterface(vlanInterface);
			CFSetAddValue(excluded, physical);
		}
		CFRelease(interfaces);
	}

	// identify available interfaces
	interfaces = __SCNetworkInterfaceCopyAll_IONetworkInterface();
	if (interfaces != NULL) {
		CFIndex	i;
		CFIndex	n;

		n = CFArrayGetCount(interfaces);
		for (i = 0; i < n; i++) {
			SCNetworkInterfaceRef		interface;
			SCNetworkInterfacePrivateRef	interfacePrivate;

			interface = CFArrayGetValueAtIndex(interfaces, i);
			interfacePrivate = (SCNetworkInterfacePrivateRef)interface;

			if (!interfacePrivate->supportsBond) {
				// if this interface is not available
				continue;
			}

			if (CFSetContainsValue(excluded, interface)) {
				// if excluded
				continue;
			}

			CFArrayAppendValue(available, interface);
		}
		CFRelease(interfaces);
	}

	CFRelease(excluded);

	return available;
}
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;
}