* 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.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38053 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2010-08-12 13:25:45 +00:00
parent 6aaaa90f38
commit 910ffb32fe
2 changed files with 45 additions and 3 deletions
@@ -535,6 +535,28 @@ Interface::AddressForDestination(net_domain* domain,
}
/*! 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 @@ Interface::Control(net_domain* domain, int32 option, ifreq& request,
!= 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 @@ Interface::Control(net_domain* domain, int32 option, ifreq& request,
}
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
@@ -122,6 +122,8 @@ public:
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);