33 #include <sys/ioctl.h>
35 #if defined(__linux__)
36 #include <netpacket/packet.h>
37 #include <sys/socket.h>
41 #if defined(__APPLE__) || defined(__FreeBSD__)
42 #include <net/if_dl.h>
51 const ethernet::Address& mcastAddress,
52 ndn::nfd::LinkType linkType)
54 #if defined(__linux__)
55 , m_interfaceIndex(localEndpoint.getIndex())
60 this->
setScope(ndn::nfd::FACE_SCOPE_NON_LOCAL);
63 this->
setMtu(localEndpoint.getMtu());
70 std::snprintf(filter,
sizeof(filter),
71 "(ether proto 0x%x) && (ether dst %s) && (not ether src %s) && (not vlan)",
72 ethernet::ETHERTYPE_NDN,
84 MulticastEthernetTransport::joinMulticastGroup()
86 #if defined(__linux__)
88 mr.mr_ifindex = m_interfaceIndex;
89 mr.mr_type = PACKET_MR_MULTICAST;
93 if (::setsockopt(
m_socket.native_handle(), SOL_PACKET,
94 PACKET_ADD_MEMBERSHIP, &mr,
sizeof(mr)) == 0)
97 NFD_LOG_FACE_WARN(
"setsockopt(PACKET_ADD_MEMBERSHIP) failed: " << std::strerror(errno));
100 #if defined(SIOCADDMULTI)
102 std::strncpy(ifr.ifr_name,
m_interfaceName.data(),
sizeof(ifr.ifr_name) - 1);
104 #if defined(__APPLE__) || defined(__FreeBSD__)
107 int fd = sock.native_handle();
120 sockaddr_dl* sdl =
reinterpret_cast<sockaddr_dl*
>(&ifr.ifr_addr);
121 sdl->sdl_len =
sizeof(ifr.ifr_addr);
122 sdl->sdl_family = AF_LINK;
126 static_assert(
sizeof(ifr.ifr_addr) >= offsetof(sockaddr_dl, sdl_data) + ethernet::ADDR_LEN,
127 "ifr_addr in struct ifreq is too small on this platform");
131 ifr.ifr_hwaddr.sa_family = AF_UNSPEC;
134 static_assert(
sizeof(ifr.ifr_hwaddr.sa_data) >= ethernet::ADDR_LEN,
135 "ifr_hwaddr in struct ifreq is too small on this platform");
138 if (::ioctl(fd, SIOCADDMULTI, &ifr) == 0)
144 NDN_THROW(Error(
"Failed to join multicast group"));
Base class for Ethernet-based Transports.
std::string m_interfaceName
boost::asio::posix::stream_descriptor m_socket
ethernet::Address m_srcAddress
ethernet::Address m_destAddress
MulticastEthernetTransport(const ndn::net::NetworkInterface &localEndpoint, const ethernet::Address &mcastAddress, ndn::nfd::LinkType linkType)
Creates an Ethernet-based transport for multicast communication.
void setPacketFilter(const char *filter) const
Install a BPF filter on the receiving socket.
void setScope(ndn::nfd::FaceScope scope) noexcept
void setPersistency(ndn::nfd::FacePersistency newPersistency)
Changes the persistency setting of the transport.
void setMtu(ssize_t mtu) noexcept
void setLocalUri(const FaceUri &uri) noexcept
void setLinkType(ndn::nfd::LinkType linkType) noexcept
void setRemoteUri(const FaceUri &uri) noexcept
#define NFD_LOG_FACE_DEBUG(msg)
Log a message at DEBUG level.
#define NFD_LOG_FACE_WARN(msg)
Log a message at WARN level.
#define NFD_LOG_INIT(name)
boost::asio::io_context & getGlobalIoService()
Returns the global io_context instance for the calling thread.