30 #include <pcap/pcap.h> 34 #include <boost/endian/conversion.hpp> 42 const ethernet::Address& remoteEndpoint)
44 , m_pcap(localEndpoint.getName())
45 , m_srcAddress(localEndpoint.getEthernetAddress())
46 , m_destAddress(remoteEndpoint)
47 , m_interfaceName(localEndpoint.getName())
48 , m_hasRecentlyReceived(false)
58 BOOST_THROW_EXCEPTION(
Error(e.what()));
61 m_netifStateConn = localEndpoint.onStateChanged.connect(
62 [=] (ndn::net::InterfaceState, ndn::net::InterfaceState newState) {
63 handleNetifStateChange(newState);
77 boost::system::error_code error;
91 EthernetTransport::handleNetifStateChange(ndn::net::InterfaceState netifState)
94 if (netifState == ndn::net::InterfaceState::RUNNING) {
109 sendPacket(packet.packet);
113 EthernetTransport::sendPacket(
const ndn::Block& block)
115 ndn::EncodingBuffer buffer(block);
118 if (block.size() < ethernet::MIN_DATA_LEN) {
119 static const uint8_t padding[ethernet::MIN_DATA_LEN] = {};
120 buffer.appendByteArray(padding, ethernet::MIN_DATA_LEN - block.size());
124 uint16_t ethertype = boost::endian::native_to_big(ethernet::ETHERTYPE_NDN);
125 buffer.prependByteArray(reinterpret_cast<const uint8_t*>(ðertype), ethernet::TYPE_LEN);
130 int sent = pcap_inject(
m_pcap, buffer.buf(), buffer.size());
133 else if (static_cast<size_t>(sent) < buffer.size())
134 handleError(
"Failed to send the full frame: size=" + to_string(buffer.size()) +
135 " sent=" + to_string(sent));
142 EthernetTransport::asyncRead()
144 m_socket.async_read_some(boost::asio::null_buffers(),
145 [
this] (
const auto& e,
auto) { this->handleRead(e); });
149 EthernetTransport::handleRead(
const boost::system::error_code& error)
154 if (error != boost::asio::error::operation_aborted &&
158 handleError(
"Receive operation failed: " + error.message());
168 if (pkt ==
nullptr) {
172 const ether_header* eh;
179 ethernet::Address sender(eh->ether_shost);
180 pkt += ethernet::HDR_LEN;
181 len -= ethernet::HDR_LEN;
188 if (nDropped - m_nDropped > 0)
190 m_nDropped = nDropped;
198 const ethernet::Address& sender)
204 std::tie(isOk, element) = Block::fromBuffer(payload, length);
210 m_hasRecentlyReceived =
true;
214 "Transport::Packet::remoteEndpoint is too small");
222 EthernetTransport::handleError(
const std::string& errorMessage)
ethernet::Address m_srcAddress
ethernet::Address m_destAddress
#define NFD_LOG_FACE_TRACE(msg)
Log a message at TRACE level.
boost::asio::posix::stream_descriptor m_socket
#define NFD_LOG_FACE_DEBUG(msg)
Log a message at DEBUG level.
void receive(Packet &&packet)
receive a link-layer packet
stores a packet along with the remote endpoint
void doClose() final
performs Transport specific operations to close the transport
the transport is being closed due to a failure
#define NFD_LOG_FACE_WARN(msg)
Log a message at WARN level.
size_t getNDropped() const
Get the number of packets dropped by the kernel, as reported by libpcap.
std::string getLastError() const
Get last error message.
Copyright (c) 2014-2015, Regents of the University of California, Arizona Board of Regents...
void receivePayload(const uint8_t *payload, size_t length, const ethernet::Address &sender)
Processes the payload of an incoming frame.
the transport is closed, and can be safely deallocated
std::tuple< const uint8_t *, size_t, std::string > readNextPacket() const
Read the next packet captured on the interface.
the transport is being closed gracefully, either by the peer or by a call to close() ...
std::pair< const ether_header *, std::string > checkFrameHeader(const uint8_t *packet, size_t length, const Address &localAddr, const Address &destAddr)
EthernetTransport(const ndn::net::NetworkInterface &localEndpoint, const ethernet::Address &remoteEndpoint)
void activate(int dlt)
Start capturing packets.
int getFd() const
Obtain a file descriptor that can be used in calls such as select(2) and poll(2). ...
ndn::nfd::FacePersistency getPersistency() const
#define NFD_LOG_INIT(name)
TransportState getState() const
void close()
Stop capturing and close the handle.
EndpointId remoteEndpoint
identifies the remote endpoint
void setState(TransportState newState)
set transport state
the transport is up and can transmit packets
#define NFD_LOG_FACE_ERROR(msg)
Log a message at ERROR level.
the transport is temporarily down, and is being recovered
boost::asio::io_service & getGlobalIoService()