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:
@@ -30,6 +30,11 @@ struct net_datalink_protocol_module_info {
|
|||||||
|
|
||||||
status_t (*control)(net_datalink_protocol *self,
|
status_t (*control)(net_datalink_protocol *self,
|
||||||
int32 op, void *argument, size_t length);
|
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
|
#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 -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
@@ -791,28 +817,11 @@ arp_send_data(net_datalink_protocol *protocol,
|
|||||||
entry->hardware_address.sdl_len);
|
entry->hardware_address.sdl_len);
|
||||||
|
|
||||||
if (buffer->flags & MSG_MCAST) {
|
if (buffer->flags & MSG_MCAST) {
|
||||||
// RFC 1112 - Host extensions for IP multicasting
|
sockaddr_dl multicastDestination;
|
||||||
//
|
ipv4_to_ether_multicast(&multicastDestination,
|
||||||
// ``An IP host group address is mapped to an Ethernet multicast
|
(sockaddr_in *)&buffer->destination);
|
||||||
// address by placing the low-order 23-bits of the IP address into
|
memcpy(&buffer->destination, &multicastDestination,
|
||||||
// the low-order 23 bits of the Ethernet multicast address
|
sizeof(multicastDestination));
|
||||||
// 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);
|
|
||||||
} else if ((buffer->flags & MSG_BCAST) == 0) {
|
} else if ((buffer->flags & MSG_BCAST) == 0) {
|
||||||
// Lookup destination (we may need to wait for this)
|
// Lookup destination (we may need to wait for this)
|
||||||
entry = arp_entry::Lookup(
|
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
|
static status_t
|
||||||
arp_std_ops(int32 op, ...)
|
arp_std_ops(int32 op, ...)
|
||||||
{
|
{
|
||||||
@@ -954,6 +991,8 @@ static net_datalink_protocol_module_info sARPModule = {
|
|||||||
arp_up,
|
arp_up,
|
||||||
arp_down,
|
arp_down,
|
||||||
arp_control,
|
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
|
static status_t
|
||||||
ethernet_frame_std_ops(int32 op, ...)
|
ethernet_frame_std_ops(int32 op, ...)
|
||||||
{
|
{
|
||||||
@@ -197,6 +213,8 @@ static net_datalink_protocol_module_info sEthernetFrameModule = {
|
|||||||
ethernet_frame_up,
|
ethernet_frame_up,
|
||||||
ethernet_frame_down,
|
ethernet_frame_down,
|
||||||
ethernet_frame_control,
|
ethernet_frame_control,
|
||||||
|
ethernet_frame_join_multicast,
|
||||||
|
ethernet_frame_leave_multicast,
|
||||||
};
|
};
|
||||||
|
|
||||||
module_info *modules[] = {
|
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
|
static status_t
|
||||||
loopback_frame_std_ops(int32 op, ...)
|
loopback_frame_std_ops(int32 op, ...)
|
||||||
{
|
{
|
||||||
@@ -158,6 +174,8 @@ static net_datalink_protocol_module_info sLoopbackFrameModule = {
|
|||||||
loopback_frame_up,
|
loopback_frame_up,
|
||||||
loopback_frame_down,
|
loopback_frame_down,
|
||||||
loopback_frame_control,
|
loopback_frame_control,
|
||||||
|
loopback_frame_join_multicast,
|
||||||
|
loopback_frame_leave_multicast,
|
||||||
};
|
};
|
||||||
|
|
||||||
module_info *modules[] = {
|
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_info gNetDatalinkModule = {
|
||||||
{
|
{
|
||||||
NET_DATALINK_MODULE_NAME,
|
NET_DATALINK_MODULE_NAME,
|
||||||
@@ -835,4 +853,6 @@ net_datalink_protocol_module_info gDatalinkInterfaceProtocolModule = {
|
|||||||
interface_protocol_up,
|
interface_protocol_up,
|
||||||
interface_protocol_down,
|
interface_protocol_down,
|
||||||
interface_protocol_control,
|
interface_protocol_control,
|
||||||
|
interface_protocol_join_multicast,
|
||||||
|
interface_protocol_leave_multicast,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user