when 0 is specified as the interface index with the generic multicast delta API, the stack should select an interface for the application.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20967 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Hugo Santos 2007-05-02 12:41:00 +00:00
parent ab7e05a39b
commit 2b1c2dd349
4 changed files with 44 additions and 22 deletions

View File

@ -258,9 +258,6 @@ ipv4_to_ether_multicast(sockaddr_dl *destination, const sockaddr_in *source)
// the low-order 23 bits of the Ethernet multicast address
// 01-00-5E-00-00-00 (hex).''
memcpy(((uint8 *)destination->sdl_data) + 2, &source->sin_addr,
sizeof(in_addr));
destination->sdl_len = sizeof(sockaddr_dl);
destination->sdl_family = AF_DLI;
destination->sdl_index = 0;
@ -269,7 +266,8 @@ ipv4_to_ether_multicast(sockaddr_dl *destination, const sockaddr_in *source)
destination->sdl_nlen = destination->sdl_slen = 0;
destination->sdl_alen = ETHER_ADDRESS_LENGTH;
uint32 *data = (uint32 *)destination->sdl_data;
memcpy(LLADDR(destination) + 2, &source->sin_addr, sizeof(in_addr));
uint32 *data = (uint32 *)LLADDR(destination);
data[0] = (data[0] & htonl(0x7f)) | htonl(0x01005e00);
}

View File

@ -97,6 +97,22 @@ ipv4_datalink_control(net_datalink_protocol *protocol, int32 op,
}
static status_t
ipv4_datalink_join_multicast(net_datalink_protocol *protocol,
const sockaddr *address)
{
return protocol->next->module->join_multicast(protocol->next, address);
}
static status_t
ipv4_datalink_leave_multicast(net_datalink_protocol *protocol,
const sockaddr *address)
{
return protocol->next->module->leave_multicast(protocol->next, address);
}
static status_t
ipv4_datalink_std_ops(int32 op, ...)
{
@ -123,6 +139,8 @@ net_datalink_protocol_module_info gIPv4DataLinkModule = {
ipv4_datalink_up,
ipv4_datalink_down,
ipv4_datalink_control,
ipv4_datalink_join_multicast,
ipv4_datalink_leave_multicast,
};
module_info *modules[] = {

View File

@ -391,8 +391,7 @@ ethernet_add_multi(struct net_device *_device, const sockaddr *_address)
if (address->sdl_type != IFT_ETHER)
return EINVAL;
return ioctl(device->fd, ETHER_ADDMULTI, address->sdl_data,
address->sdl_alen);
return ioctl(device->fd, ETHER_ADDMULTI, LLADDR(address), 6);
}
@ -408,8 +407,7 @@ ethernet_rem_multi(struct net_device *_device, const sockaddr *_address)
if (address->sdl_type != IFT_ETHER)
return EINVAL;
return ioctl(device->fd, ETHER_REMMULTI, address->sdl_data,
address->sdl_alen);
return ioctl(device->fd, ETHER_REMMULTI, LLADDR(address), 6);
}

View File

@ -706,20 +706,26 @@ raw_receive_data(net_buffer *buffer)
}
static sockaddr *
fill_sockaddr_in(sockaddr_in *destination, const in_addr &source)
{
memset(destination, 0, sizeof(sockaddr_in));
destination->sin_family = AF_INET;
destination->sin_addr = source;
return (sockaddr *)destination;
}
status_t
IPv4Multicast::JoinGroup(IPv4GroupInterface *state)
{
BenaphoreLocker _(sMulticastGroupsLock);
sockaddr_in groupAddr;
memset(&groupAddr, 0, sizeof(groupAddr));
groupAddr.sin_addr = state->Address();
net_interface *intf = state->Interface();
status_t status =
intf->first_protocol->module->join_multicast(intf->first_protocol,
(sockaddr *)&groupAddr);
status_t status = intf->first_info->join_multicast(intf->first_protocol,
fill_sockaddr_in(&groupAddr, state->Address()));
if (status < B_OK)
return status;
@ -736,13 +742,10 @@ IPv4Multicast::LeaveGroup(IPv4GroupInterface *state)
sMulticastState->Remove(state);
sockaddr_in groupAddr;
memset(&groupAddr, 0, sizeof(groupAddr));
groupAddr.sin_addr = state->Address();
net_interface *intf = state->Interface();
return intf->first_protocol->module->join_multicast(intf->first_protocol,
(sockaddr *)&groupAddr);
fill_sockaddr_in(&groupAddr, state->Address()));
}
@ -913,14 +916,19 @@ ipv4_generic_delta_membership(ipv4_protocol *protocol, int option,
if (_sourceAddr && _sourceAddr->ss_family != AF_INET)
return EINVAL;
net_interface *interface = sDatalinkModule->get_interface(sDomain, index);
if (interface == NULL)
return ENODEV;
net_interface *interface;
const in_addr *groupAddr, *sourceAddr = NULL;
groupAddr = &((const sockaddr_in *)_groupAddr)->sin_addr;
if (index == 0)
interface = get_multicast_interface(protocol, groupAddr);
else
interface = sDatalinkModule->get_interface(sDomain, index);
if (interface == NULL)
return ENODEV;
if (_sourceAddr)
sourceAddr = &((const sockaddr_in *)_sourceAddr)->sin_addr;