Author: axeld Date: 2010-08-12 15:25:45 +0200 (Thu, 12 Aug 2010) New Revision: 38053 Changeset: http://dev.haiku-os.org/changeset/38053 Modified: haiku/trunk/src/add-ons/kernel/network/stack/interfaces.cpp haiku/trunk/src/add-ons/kernel/network/stack/interfaces.h Log: * If the network mask, and broadcast are not specified with a B_SOCKET_SET_ALIAS they will no longer be unset - instead they are set with defaults. * If B_SOCKET_SET_ALIAS gets an index of -1, it will now try to find the local address, and if that fails, will just use the first address there is. Modified: haiku/trunk/src/add-ons/kernel/network/stack/interfaces.cpp =================================================================== --- haiku/trunk/src/add-ons/kernel/network/stack/interfaces.cpp 2010-08-12 13:23:40 UTC (rev 38052) +++ haiku/trunk/src/add-ons/kernel/network/stack/interfaces.cpp 2010-08-12 13:25:45 UTC (rev 38053) @@ -535,6 +535,28 @@ } +/*! Returns a reference to the InterfaceAddress that has the specified + \a local address. +*/ +InterfaceAddress* +Interface::AddressForLocal(net_domain* domain, const sockaddr* local) +{ + RecursiveLocker locker(fLock); + + AddressList::Iterator iterator = fAddresses.GetIterator(); + while (InterfaceAddress* address = iterator.Next()) { + if (address->domain == domain + && address->local != NULL + && domain->address_module->equal_addresses(address->local, local)) { + address->AcquireReference(); + return address; + } + } + + return NULL; +} + + status_t Interface::AddAddress(InterfaceAddress* address) { @@ -690,7 +712,21 @@ != B_OK) return B_BAD_ADDRESS; - InterfaceAddress* address = AddressAt(aliasRequest.ifra_index); + InterfaceAddress* address = NULL; + if (aliasRequest.ifra_index < 0) { + if (!domain->address_module->is_empty_address( + (const sockaddr*)&aliasRequest.ifra_addr, false)) { + // Find first address that matches the local address + address = AddressForLocal(domain, + (const sockaddr*)&aliasRequest.ifra_addr); + } + if (address == NULL) { + // Find first address for family + address = FirstForFamily(domain->family); + } + } else + address = AddressAt(aliasRequest.ifra_index); + if (address == NULL) return B_BAD_VALUE; @@ -706,14 +742,18 @@ } if (status == B_OK && !domain->address_module->equal_addresses( - (sockaddr*)&aliasRequest.ifra_mask, address->mask)) { + (sockaddr*)&aliasRequest.ifra_mask, address->mask) + && !domain->address_module->is_empty_address( + (sockaddr*)&aliasRequest.ifra_mask, false)) { status = _ChangeAddress(locker, address, SIOCSIFNETMASK, address->mask, (sockaddr*)&aliasRequest.ifra_mask); } if (status == B_OK && !domain->address_module->equal_addresses( (sockaddr*)&aliasRequest.ifra_destination, - address->destination)) { + address->destination) + && !domain->address_module->is_empty_address( + (sockaddr*)&aliasRequest.ifra_destination, false)) { status = _ChangeAddress(locker, address, (domain->address_module->flags & NET_ADDRESS_MODULE_FLAG_BROADCAST_ADDRESS) != 0 Modified: haiku/trunk/src/add-ons/kernel/network/stack/interfaces.h =================================================================== --- haiku/trunk/src/add-ons/kernel/network/stack/interfaces.h 2010-08-12 13:23:40 UTC (rev 38052) +++ haiku/trunk/src/add-ons/kernel/network/stack/interfaces.h 2010-08-12 13:25:45 UTC (rev 38053) @@ -122,6 +122,8 @@ InterfaceAddress* FirstUnconfiguredForFamily(int family); InterfaceAddress* AddressForDestination(net_domain* domain, const sockaddr* destination); + InterfaceAddress* AddressForLocal(net_domain* domain, + const sockaddr* local); status_t AddAddress(InterfaceAddress* address); void RemoveAddress(InterfaceAddress* address);