diff --git a/src/add-ons/kernel/network/datalink_protocols/arp/arp.cpp b/src/add-ons/kernel/network/datalink_protocols/arp/arp.cpp index b8e9b6eadc..274d8c3c5e 100644 --- a/src/add-ons/kernel/network/datalink_protocols/arp/arp.cpp +++ b/src/add-ons/kernel/network/datalink_protocols/arp/arp.cpp @@ -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); } diff --git a/src/add-ons/kernel/network/datalink_protocols/ipv4_datagram/ipv4_datagram.cpp b/src/add-ons/kernel/network/datalink_protocols/ipv4_datagram/ipv4_datagram.cpp index eee76dac2f..3f163ee3e4 100644 --- a/src/add-ons/kernel/network/datalink_protocols/ipv4_datagram/ipv4_datagram.cpp +++ b/src/add-ons/kernel/network/datalink_protocols/ipv4_datagram/ipv4_datagram.cpp @@ -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[] = { diff --git a/src/add-ons/kernel/network/devices/ethernet/ethernet.cpp b/src/add-ons/kernel/network/devices/ethernet/ethernet.cpp index 3c1a99d4bb..f1d6b8d8c2 100644 --- a/src/add-ons/kernel/network/devices/ethernet/ethernet.cpp +++ b/src/add-ons/kernel/network/devices/ethernet/ethernet.cpp @@ -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); } diff --git a/src/add-ons/kernel/network/protocols/ipv4/ipv4.cpp b/src/add-ons/kernel/network/protocols/ipv4/ipv4.cpp index dd19b910b1..58bc1c256c 100644 --- a/src/add-ons/kernel/network/protocols/ipv4/ipv4.cpp +++ b/src/add-ons/kernel/network/protocols/ipv4/ipv4.cpp @@ -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;