}
prefix_ void senf::INet4MulticastSocketProtocol::mcAddMembership(INet4Address const & mcAddr,
- INet4Address const & localAddr)
+ INet4Address const & localAddr)
const
{
struct ip_mreqn mreqn;
}
prefix_ void senf::INet4MulticastSocketProtocol::mcAddMembership(INet4Address const & mcAddr,
- std::string const & iface)
+ std::string const & iface)
const
{
struct ip_mreqn mreqn;
}
prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address const & mcAddr,
- INet4Address const & localAddr)
+ INet4Address const & localAddr)
const
{
struct ip_mreqn mreqn;
}
prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address const & mcAddr,
- std::string const & iface)
+ std::string const & iface)
const
{
struct ip_mreqn mreqn;
prefix_ void senf::INet6MulticastSocketProtocol::mcAddMembership(INet6Address const & mcAddr)
const
{
- struct ipv6_mreq mreqn;
- std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr);
- mreqn.ipv6mr_interface = 0;
- if (::setsockopt(fd(),SOL_IPV6,IPV6_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
- SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IPV6_ADD_MEMBERSHIP");
+ if (mcAddr.inet4Mapped()) {
+ struct ip_mreqn mreqn;
+ mreqn.imr_multiaddr.s_addr = mcAddr.inet4address().inaddr();
+ mreqn.imr_address.s_addr = htons(INADDR_ANY);
+ mreqn.imr_ifindex = 0;
+ if (::setsockopt(fd(),SOL_IP,IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
+ SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IP_ADD_MEMBERSHIP)");
+ }
+ else {
+ struct ipv6_mreq mreqn;
+ std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr);
+ mreqn.ipv6mr_interface = 0;
+ if (::setsockopt(fd(),SOL_IPV6,IPV6_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
+ SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IPV6_ADD_MEMBERSHIP");
+ }
}
prefix_ void senf::INet6MulticastSocketProtocol::mcAddMembership(INet6Address const & mcAddr,
- std::string const & iface)
+ std::string const & iface)
{
- struct ipv6_mreq mreqn;
- std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr);
- mreqn.ipv6mr_interface = if_nametoindex(iface.c_str());
- if (mreqn.ipv6mr_interface == 0)
- throw SystemException("::if_nametoindex()",ENOENT SENF_EXC_DEBUGINFO);
- if (::setsockopt(fd(),SOL_IPV6,IPV6_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
- SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IPV6_ADD_MEMBERSHIP");
+ if (mcAddr.inet4Mapped()) {
+ struct ip_mreqn mreqn;
+ mreqn.imr_multiaddr.s_addr = mcAddr.inet4address().inaddr();
+ mreqn.imr_address.s_addr = htons(INADDR_ANY);
+ mreqn.imr_ifindex = if_nametoindex(iface.c_str());
+ if (mreqn.imr_ifindex == 0)
+ throw SystemException("::if_nametoindex()",ENOENT SENF_EXC_DEBUGINFO);
+ if (::setsockopt(fd(),SOL_IP,IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
+ SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IP_ADD_MEMBERSHIP");
+ }
+ else {
+ struct ipv6_mreq mreqn;
+ std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr);
+ mreqn.ipv6mr_interface = if_nametoindex(iface.c_str());
+ if (mreqn.ipv6mr_interface == 0)
+ throw SystemException("::if_nametoindex()",ENOENT SENF_EXC_DEBUGINFO);
+ if (::setsockopt(fd(),SOL_IPV6,IPV6_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
+ SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IPV6_ADD_MEMBERSHIP");
+ }
}
prefix_ void senf::INet6MulticastSocketProtocol::mcDropMembership(INet6Address const & mcAddr)
const
{
- struct ipv6_mreq mreqn;
- std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr);
- mreqn.ipv6mr_interface = 0;
- if (::setsockopt(fd(),SOL_IPV6,IPV6_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
- SENF_THROW_SYSTEM_EXCEPTION("");
+ if (mcAddr.inet4Mapped()) {
+ struct ip_mreqn mreqn;
+ mreqn.imr_multiaddr.s_addr = mcAddr.inet4address().inaddr();
+ mreqn.imr_address.s_addr = htons(INADDR_ANY);
+ mreqn.imr_ifindex = 0;
+ if (::setsockopt(fd(),SOL_IP,IP_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
+ SENF_THROW_SYSTEM_EXCEPTION("");
+ }
+ else {
+ struct ipv6_mreq mreqn;
+ std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr);
+ mreqn.ipv6mr_interface = 0;
+ if (::setsockopt(fd(),SOL_IPV6,IPV6_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
+ SENF_THROW_SYSTEM_EXCEPTION("");
+ }
}
prefix_ void
senf::INet6MulticastSocketProtocol::mcDropMembership(INet6Address const & mcAddr,
- std::string const & iface)
+ std::string const & iface)
const
{
- struct ipv6_mreq mreqn;
- std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr);
- mreqn.ipv6mr_interface = if_nametoindex(iface.c_str());
- if (mreqn.ipv6mr_interface == 0)
- throw SystemException("::if_nametoindex()",ENOENT SENF_EXC_DEBUGINFO);
- if (::setsockopt(fd(),SOL_IPV6,IPV6_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
- SENF_THROW_SYSTEM_EXCEPTION("");
+ if (mcAddr.inet4Mapped()) {
+ struct ip_mreqn mreqn;
+ mreqn.imr_multiaddr.s_addr = mcAddr.inet4address().inaddr();
+ mreqn.imr_address.s_addr = htons(INADDR_ANY);
+ mreqn.imr_ifindex = if_nametoindex(iface.c_str());
+ if (mreqn.imr_ifindex == 0)
+ throw SystemException("::if_nametoindex()",ENOENT SENF_EXC_DEBUGINFO);
+ if (::setsockopt(fd(),SOL_IP,IP_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
+ SENF_THROW_SYSTEM_EXCEPTION("");
+ }
+ else {
+ struct ipv6_mreq mreqn;
+ std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr);
+ mreqn.ipv6mr_interface = if_nametoindex(iface.c_str());
+ if (mreqn.ipv6mr_interface == 0)
+ throw SystemException("::if_nametoindex()",ENOENT SENF_EXC_DEBUGINFO);
+ if (::setsockopt(fd(),SOL_IPV6,IPV6_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
+ SENF_THROW_SYSTEM_EXCEPTION("");
+ }
}
///////////////////////////////cc.e////////////////////////////////////////
};
/** \brief Multicast protocol facet for INet6 addressable multicast enabled sockets
+
+ This implementation supports INet6 mapped INet4 multicast addresses. This is a linux
+ specific extension and NOT part of the relevant RFCs.
*/
class INet6MulticastSocketProtocol
: public MulticastSocketProtocol
groups received. The group is joined on the default
interface.
\param[in] mcAddr address of group to join */
- void mcAddMembership(INet6Address const & mcAddr, INet6Address const & localAddr)
- const;
- ///< join multicast group on a specific interface
- /**< This member will add \a mcAddr to the list of multicast
- groups received. The group is joined on the interface
- with the given local address.
- \param[in] mcAddr address of group to join
- \param[in] localAddr address of interface to join on */
void mcAddMembership(INet6Address const & mcAddr, std::string const & iface);
///< join multicast group on a specific interface
/**< This member will add \a mcAddr to the list of multicast
multicast groups received. The group is left from the
default interface.
\param[in] mcAddr address of group to leave */
- void mcDropMembership(INet6Address const & mcAddr, INet6Address const & localAddr)
- const;
- ///< leave multicast group on a specific interface
- /**< This member will remove \a mcAddr from the list of
- multicast groups received. The group is left from the
- interface with the given local address.
- \param[in] mcAddr address of group to leave
- \param[in] localAddr address of interface to leave
- from */
void mcDropMembership(INet6Address const & mcAddr, std::string const & iface)
const;
///< leave multicast group on a specific interface