Beispiel #1
0
/*!	Returns a reference to an InterfaceAddress of the specified \a domain that
	belongs to the interface identified via \a linkAddress. Only the hardware
	address is matched.

	If \a unconfiguredOnly is set, the interface address must not yet be
	configured, or must currently be in the process of being configured.
*/
InterfaceAddress*
get_interface_address_for_link(net_domain* domain, const sockaddr* address,
	bool unconfiguredOnly)
{
	sockaddr_dl& linkAddress = *(sockaddr_dl*)address;

	RecursiveLocker locker(sLock);

	InterfaceList::Iterator iterator = sInterfaces.GetIterator();
	while (Interface* interface = iterator.Next()) {
		if (interface->IsBusy())
			continue;
		// Test if the hardware address matches, or if the given interface
		// matches, or if at least the index matches.
		if (linkAddress.sdl_alen == interface->device->address.length
			&& memcmp(LLADDR(&linkAddress), interface->device->address.data,
				linkAddress.sdl_alen) == 0) {
			TRACE("  %s matches\n", interface->name);
			// link address matches
			if (unconfiguredOnly)
				return interface->FirstUnconfiguredForFamily(domain->family);

			return interface->FirstForFamily(domain->family);
		}
	}

	return NULL;
}
Beispiel #2
0
/*!	Returns a reference to an Interface that matches the given \a linkAddress.
	The link address is checked against its hardware address, or its interface
	name, or finally the interface index.
*/
Interface*
get_interface_for_link(net_domain* domain, const sockaddr* _linkAddress)
{
	sockaddr_dl& linkAddress = *(sockaddr_dl*)_linkAddress;

	RecursiveLocker locker(sLock);

	InterfaceList::Iterator iterator = sInterfaces.GetIterator();
	while (Interface* interface = iterator.Next()) {
		if (interface->IsBusy())
			continue;
		// Test if the hardware address matches, or if the given interface
		// matches, or if at least the index matches.
		if ((linkAddress.sdl_alen == interface->device->address.length
				&& memcmp(LLADDR(&linkAddress), interface->device->address.data,
					linkAddress.sdl_alen) == 0)
			|| (linkAddress.sdl_nlen > 0
				&& !strcmp(interface->name, (const char*)linkAddress.sdl_data))
			|| (linkAddress.sdl_nlen == 0 && linkAddress.sdl_alen == 0
				&& linkAddress.sdl_index == interface->index)) {
			if (interface->IsBusy())
				return NULL;
			if (interface->CreateDomainDatalinkIfNeeded(domain) != B_OK)
				return NULL;

			interface->AcquireReference();
			return interface;
		}
	}

	return NULL;
}
Beispiel #3
0
static int
dump_interfaces(int argc, char** argv)
{
	InterfaceList::Iterator iterator = sInterfaces.GetIterator();
	while (Interface* interface = iterator.Next()) {
		kprintf("%p  %s\n", interface, interface->name);
	}
	return 0;
}
Beispiel #4
0
//! For debugging purposes only
void
dump_interface_refs(void)
{
	RecursiveLocker locker(sLock);

	InterfaceList::Iterator iterator = sInterfaces.GetIterator();
	while (Interface* interface = iterator.Next()) {
		dprintf("%p: %s, %ld\n", interface, interface->name,
			interface->CountReferences());
	}
}
Beispiel #5
0
/*!	Searches for a specific interface by index.
	You need to have the interface list's lock hold when calling this function.
*/
static struct Interface*
find_interface(uint32 index)
{
	InterfaceList::Iterator iterator = sInterfaces.GetIterator();
	while (Interface* interface = iterator.Next()) {
		if (interface->index == index)
			return interface;
	}

	return NULL;
}
Beispiel #6
0
/*!	Searches for a specific interface by name.
	You need to have the interface list's lock hold when calling this function.
*/
static struct Interface*
find_interface(const char* name)
{
	ASSERT_LOCKED_RECURSIVE(&sLock);

	InterfaceList::Iterator iterator = sInterfaces.GetIterator();
	while (Interface* interface = iterator.Next()) {
		if (!strcmp(interface->name, name))
			return interface;
	}

	return NULL;
}
Beispiel #7
0
/*!	Dumps a list of all interfaces into the supplied userland buffer.
	If the interfaces don't fit into the buffer, an error (\c ENOBUFS) is
	returned.
*/
status_t
list_interfaces(int family, void* _buffer, size_t* bufferSize)
{
	RecursiveLocker locker(sLock);

	UserBuffer buffer(_buffer, *bufferSize);

	InterfaceList::Iterator iterator = sInterfaces.GetIterator();
	while (Interface* interface = iterator.Next()) {
		// Copy name
		buffer.Push(interface->name, IF_NAMESIZE);

		// Copy address
		InterfaceAddress* address = interface->FirstForFamily(family);
		size_t length = 0;

		if (address != NULL && address->local != NULL) {
			// Actual address
			buffer.Push(address->local, length = address->local->sa_len);
		} else {
			// Empty address
			sockaddr empty;
			empty.sa_len = 2;
			empty.sa_family = AF_UNSPEC;
			buffer.Push(&empty, length = empty.sa_len);
		}

		if (address != NULL)
			address->ReleaseReference();

		if (IF_NAMESIZE + length < sizeof(ifreq)) {
			// Make sure at least sizeof(ifreq) bytes are written for each
			// interface for compatibility with other platforms
			buffer.Pad(sizeof(ifreq) - IF_NAMESIZE - length);
		}

		if (buffer.Status() != B_OK)
			return buffer.Status();
	}

	*bufferSize = buffer.BytesConsumed();
	return B_OK;
}
Beispiel #8
0
InterfaceAddress*
get_interface_address_for_destination(net_domain* domain,
	const sockaddr* destination)
{
	RecursiveLocker locker(sLock);

	InterfaceList::Iterator iterator = sInterfaces.GetIterator();
	while (Interface* interface = iterator.Next()) {
		if (interface->IsBusy())
			continue;

		InterfaceAddress* address
			= interface->AddressForDestination(domain, destination);
		if (address != NULL)
			return address;
	}

	return NULL;
}
Beispiel #9
0
Interface*
get_interface_for_device(net_domain* domain, uint32 index)
{
	RecursiveLocker locker(sLock);

	InterfaceList::Iterator iterator = sInterfaces.GetIterator();
	while (Interface* interface = iterator.Next()) {
		if (interface->device->index == index) {
			if (interface->IsBusy())
				return NULL;
			if (interface->CreateDomainDatalinkIfNeeded(domain) != B_OK)
				return NULL;

			interface->AcquireReference();
			return interface;
		}
	}

	return NULL;
}
Beispiel #10
0
static int
dump_interface(int argc, char** argv)
{
	if (argc != 2) {
		kprintf("usage: %s [name|address]\n", argv[0]);
		return 0;
	}

	Interface* interface = NULL;

	InterfaceList::Iterator iterator = sInterfaces.GetIterator();
	while ((interface = iterator.Next()) != NULL) {
		if (!strcmp(argv[1], interface->name))
			break;
	}

	if (interface == NULL)
		interface = (Interface*)parse_expression(argv[1]);

	interface->Dump();

	return 0;
}