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:
parent
ab7e05a39b
commit
2b1c2dd349
@ -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
|
// the low-order 23 bits of the Ethernet multicast address
|
||||||
// 01-00-5E-00-00-00 (hex).''
|
// 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_len = sizeof(sockaddr_dl);
|
||||||
destination->sdl_family = AF_DLI;
|
destination->sdl_family = AF_DLI;
|
||||||
destination->sdl_index = 0;
|
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_nlen = destination->sdl_slen = 0;
|
||||||
destination->sdl_alen = ETHER_ADDRESS_LENGTH;
|
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);
|
data[0] = (data[0] & htonl(0x7f)) | htonl(0x01005e00);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
static status_t
|
||||||
ipv4_datalink_std_ops(int32 op, ...)
|
ipv4_datalink_std_ops(int32 op, ...)
|
||||||
{
|
{
|
||||||
@ -123,6 +139,8 @@ net_datalink_protocol_module_info gIPv4DataLinkModule = {
|
|||||||
ipv4_datalink_up,
|
ipv4_datalink_up,
|
||||||
ipv4_datalink_down,
|
ipv4_datalink_down,
|
||||||
ipv4_datalink_control,
|
ipv4_datalink_control,
|
||||||
|
ipv4_datalink_join_multicast,
|
||||||
|
ipv4_datalink_leave_multicast,
|
||||||
};
|
};
|
||||||
|
|
||||||
module_info *modules[] = {
|
module_info *modules[] = {
|
||||||
|
@ -391,8 +391,7 @@ ethernet_add_multi(struct net_device *_device, const sockaddr *_address)
|
|||||||
if (address->sdl_type != IFT_ETHER)
|
if (address->sdl_type != IFT_ETHER)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
return ioctl(device->fd, ETHER_ADDMULTI, address->sdl_data,
|
return ioctl(device->fd, ETHER_ADDMULTI, LLADDR(address), 6);
|
||||||
address->sdl_alen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -408,8 +407,7 @@ ethernet_rem_multi(struct net_device *_device, const sockaddr *_address)
|
|||||||
if (address->sdl_type != IFT_ETHER)
|
if (address->sdl_type != IFT_ETHER)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
return ioctl(device->fd, ETHER_REMMULTI, address->sdl_data,
|
return ioctl(device->fd, ETHER_REMMULTI, LLADDR(address), 6);
|
||||||
address->sdl_alen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
status_t
|
||||||
IPv4Multicast::JoinGroup(IPv4GroupInterface *state)
|
IPv4Multicast::JoinGroup(IPv4GroupInterface *state)
|
||||||
{
|
{
|
||||||
BenaphoreLocker _(sMulticastGroupsLock);
|
BenaphoreLocker _(sMulticastGroupsLock);
|
||||||
|
|
||||||
sockaddr_in groupAddr;
|
sockaddr_in groupAddr;
|
||||||
memset(&groupAddr, 0, sizeof(groupAddr));
|
|
||||||
groupAddr.sin_addr = state->Address();
|
|
||||||
|
|
||||||
net_interface *intf = state->Interface();
|
net_interface *intf = state->Interface();
|
||||||
|
|
||||||
status_t status =
|
status_t status = intf->first_info->join_multicast(intf->first_protocol,
|
||||||
intf->first_protocol->module->join_multicast(intf->first_protocol,
|
fill_sockaddr_in(&groupAddr, state->Address()));
|
||||||
(sockaddr *)&groupAddr);
|
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@ -736,13 +742,10 @@ IPv4Multicast::LeaveGroup(IPv4GroupInterface *state)
|
|||||||
sMulticastState->Remove(state);
|
sMulticastState->Remove(state);
|
||||||
|
|
||||||
sockaddr_in groupAddr;
|
sockaddr_in groupAddr;
|
||||||
memset(&groupAddr, 0, sizeof(groupAddr));
|
|
||||||
groupAddr.sin_addr = state->Address();
|
|
||||||
|
|
||||||
net_interface *intf = state->Interface();
|
net_interface *intf = state->Interface();
|
||||||
|
|
||||||
return intf->first_protocol->module->join_multicast(intf->first_protocol,
|
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)
|
if (_sourceAddr && _sourceAddr->ss_family != AF_INET)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
net_interface *interface = sDatalinkModule->get_interface(sDomain, index);
|
net_interface *interface;
|
||||||
if (interface == NULL)
|
|
||||||
return ENODEV;
|
|
||||||
|
|
||||||
const in_addr *groupAddr, *sourceAddr = NULL;
|
const in_addr *groupAddr, *sourceAddr = NULL;
|
||||||
|
|
||||||
groupAddr = &((const sockaddr_in *)_groupAddr)->sin_addr;
|
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)
|
if (_sourceAddr)
|
||||||
sourceAddr = &((const sockaddr_in *)_sourceAddr)->sin_addr;
|
sourceAddr = &((const sockaddr_in *)_sourceAddr)->sin_addr;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user