added join_multicast/leave_multicast to datalink protocols, preparing for full multicast support.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20944 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
5d1514bdd9
commit
1a41adbcd2
@ -30,6 +30,11 @@ struct net_datalink_protocol_module_info {
|
||||
|
||||
status_t (*control)(net_datalink_protocol *self,
|
||||
int32 op, void *argument, size_t length);
|
||||
|
||||
status_t (*join_multicast)(net_datalink_protocol *self,
|
||||
const sockaddr *address);
|
||||
status_t (*leave_multicast)(net_datalink_protocol *self,
|
||||
const sockaddr *address);
|
||||
};
|
||||
|
||||
#endif // NET_DATALINK_PROTOCOL_H
|
||||
|
@ -248,6 +248,32 @@ arp_entry::MarkValid()
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ipv4_to_ether_multicast(sockaddr_dl *destination, const sockaddr_in *source)
|
||||
{
|
||||
// RFC 1112 - Host extensions for IP multicasting
|
||||
//
|
||||
// ``An IP host group address is mapped to an Ethernet multicast
|
||||
// address by placing the low-order 23-bits of the IP address into
|
||||
// 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;
|
||||
destination->sdl_type = IFT_ETHER;
|
||||
destination->sdl_e_type = ETHER_TYPE_IP;
|
||||
destination->sdl_nlen = destination->sdl_slen = 0;
|
||||
destination->sdl_alen = ETHER_ADDRESS_LENGTH;
|
||||
|
||||
uint32 *data = (uint32 *)destination->sdl_data;
|
||||
data[0] = (data[0] & htonl(0x7f)) | htonl(0x01005e00);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
@ -791,28 +817,11 @@ arp_send_data(net_datalink_protocol *protocol,
|
||||
entry->hardware_address.sdl_len);
|
||||
|
||||
if (buffer->flags & MSG_MCAST) {
|
||||
// RFC 1112 - Host extensions for IP multicasting
|
||||
//
|
||||
// ``An IP host group address is mapped to an Ethernet multicast
|
||||
// address by placing the low-order 23-bits of the IP address into
|
||||
// the low-order 23 bits of the Ethernet multicast address
|
||||
// 01-00-5E-00-00-00 (hex).''
|
||||
|
||||
sockaddr_dl *destination = (sockaddr_dl *)&buffer->destination;
|
||||
|
||||
memmove(((uint8 *)destination->sdl_data) + 2,
|
||||
&((sockaddr_in *)&buffer->destination)->sin_addr, sizeof(in_addr));
|
||||
|
||||
destination->sdl_len = sizeof(sockaddr_dl);
|
||||
destination->sdl_family = AF_DLI;
|
||||
destination->sdl_index = 0;
|
||||
destination->sdl_type = IFT_ETHER;
|
||||
destination->sdl_e_type = ETHER_TYPE_IP;
|
||||
destination->sdl_nlen = destination->sdl_slen = 0;
|
||||
destination->sdl_alen = ETHER_ADDRESS_LENGTH;
|
||||
|
||||
uint32 *data = (uint32 *)destination->sdl_data;
|
||||
data[0] = (data[0] & htonl(0x7f)) | htonl(0x01005e00);
|
||||
sockaddr_dl multicastDestination;
|
||||
ipv4_to_ether_multicast(&multicastDestination,
|
||||
(sockaddr_in *)&buffer->destination);
|
||||
memcpy(&buffer->destination, &multicastDestination,
|
||||
sizeof(multicastDestination));
|
||||
} else if ((buffer->flags & MSG_BCAST) == 0) {
|
||||
// Lookup destination (we may need to wait for this)
|
||||
entry = arp_entry::Lookup(
|
||||
@ -927,6 +936,34 @@ arp_control(net_datalink_protocol *protocol,
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
arp_join_multicast(net_datalink_protocol *protocol, const sockaddr *address)
|
||||
{
|
||||
if (address->sa_family != AF_INET)
|
||||
return EINVAL;
|
||||
|
||||
sockaddr_dl multicastAddress;
|
||||
ipv4_to_ether_multicast(&multicastAddress, (const sockaddr_in *)address);
|
||||
|
||||
return protocol->next->module->join_multicast(protocol->next,
|
||||
(sockaddr *)&multicastAddress);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
arp_leave_multicast(net_datalink_protocol *protocol, const sockaddr *address)
|
||||
{
|
||||
if (address->sa_family != AF_INET)
|
||||
return EINVAL;
|
||||
|
||||
sockaddr_dl multicastAddress;
|
||||
ipv4_to_ether_multicast(&multicastAddress, (const sockaddr_in *)address);
|
||||
|
||||
return protocol->next->module->leave_multicast(protocol->next,
|
||||
(sockaddr *)&multicastAddress);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
arp_std_ops(int32 op, ...)
|
||||
{
|
||||
@ -954,6 +991,8 @@ static net_datalink_protocol_module_info sARPModule = {
|
||||
arp_up,
|
||||
arp_down,
|
||||
arp_control,
|
||||
arp_join_multicast,
|
||||
arp_leave_multicast,
|
||||
};
|
||||
|
||||
|
||||
|
@ -169,6 +169,22 @@ ethernet_frame_control(net_datalink_protocol *protocol,
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
ethernet_frame_join_multicast(net_datalink_protocol *protocol,
|
||||
const sockaddr *address)
|
||||
{
|
||||
return protocol->next->module->join_multicast(protocol, address);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
ethernet_frame_leave_multicast(net_datalink_protocol *protocol,
|
||||
const sockaddr *address)
|
||||
{
|
||||
return protocol->next->module->leave_multicast(protocol, address);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
ethernet_frame_std_ops(int32 op, ...)
|
||||
{
|
||||
@ -197,6 +213,8 @@ static net_datalink_protocol_module_info sEthernetFrameModule = {
|
||||
ethernet_frame_up,
|
||||
ethernet_frame_down,
|
||||
ethernet_frame_control,
|
||||
ethernet_frame_join_multicast,
|
||||
ethernet_frame_leave_multicast,
|
||||
};
|
||||
|
||||
module_info *modules[] = {
|
||||
|
@ -130,6 +130,22 @@ loopback_frame_control(net_datalink_protocol *protocol,
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
loopback_frame_join_multicast(net_datalink_protocol *protocol,
|
||||
const sockaddr *address)
|
||||
{
|
||||
return protocol->next->module->join_multicast(protocol, address);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
loopback_frame_leave_multicast(net_datalink_protocol *protocol,
|
||||
const sockaddr *address)
|
||||
{
|
||||
return protocol->next->module->leave_multicast(protocol, address);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
loopback_frame_std_ops(int32 op, ...)
|
||||
{
|
||||
@ -158,6 +174,8 @@ static net_datalink_protocol_module_info sLoopbackFrameModule = {
|
||||
loopback_frame_up,
|
||||
loopback_frame_down,
|
||||
loopback_frame_control,
|
||||
loopback_frame_join_multicast,
|
||||
loopback_frame_leave_multicast,
|
||||
};
|
||||
|
||||
module_info *modules[] = {
|
||||
|
@ -799,6 +799,24 @@ interface_protocol_control(net_datalink_protocol *_protocol,
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
interface_protocol_join_multicast(net_datalink_protocol *_protocol,
|
||||
const sockaddr *address)
|
||||
{
|
||||
// TODO
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
interface_protocol_leave_multicast(net_datalink_protocol *_protocol,
|
||||
const sockaddr *address)
|
||||
{
|
||||
// TODO
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
|
||||
net_datalink_module_info gNetDatalinkModule = {
|
||||
{
|
||||
NET_DATALINK_MODULE_NAME,
|
||||
@ -835,4 +853,6 @@ net_datalink_protocol_module_info gDatalinkInterfaceProtocolModule = {
|
||||
interface_protocol_up,
|
||||
interface_protocol_down,
|
||||
interface_protocol_control,
|
||||
interface_protocol_join_multicast,
|
||||
interface_protocol_leave_multicast,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user