blob: e9f0e2a27076f5bd33e072fe91c1d84b39962f63 [file] [log] [blame]
Davide Pesavento44deacc2014-02-19 10:48:07 +01001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Junxiao Shi1e46be32015-01-08 20:18:05 -07003 * Copyright (c) 2014-2015, Regents of the University of California,
4 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -070010 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Steve DiBenedettoef04f272014-06-04 14:28:31 -060024 */
Davide Pesavento44deacc2014-02-19 10:48:07 +010025
Alexander Afanasyev613e2a92014-04-15 13:36:58 -070026#ifndef NFD_DAEMON_FACE_ETHERNET_FACE_HPP
27#define NFD_DAEMON_FACE_ETHERNET_FACE_HPP
Davide Pesavento44deacc2014-02-19 10:48:07 +010028
Davide Pesavento7726ae52014-11-23 21:01:05 +010029#include "common.hpp"
Davide Pesavento44deacc2014-02-19 10:48:07 +010030#include "face.hpp"
Matteo Sammarco66df9742014-11-21 18:31:26 +010031#include "ndnlp-partial-message-store.hpp"
32#include "ndnlp-slicer.hpp"
Junxiao Shia1937bf2014-11-06 11:43:40 -070033#include "core/network-interface.hpp"
Davide Pesavento44deacc2014-02-19 10:48:07 +010034
Matteo Sammarco66df9742014-11-21 18:31:26 +010035#include <unordered_map>
36
Alexander Afanasyev885a85b2014-04-12 21:01:13 -070037#ifndef HAVE_LIBPCAP
38#error "Cannot include this file when libpcap is not available"
Davide Pesavento44deacc2014-02-19 10:48:07 +010039#endif
40
41// forward declarations
42struct pcap;
43typedef pcap pcap_t;
Davide Pesavento7726ae52014-11-23 21:01:05 +010044struct pcap_pkthdr;
Davide Pesavento44deacc2014-02-19 10:48:07 +010045
46namespace nfd {
47
48/**
Davide Pesavento7726ae52014-11-23 21:01:05 +010049 * @brief Implementation of Face abstraction that uses raw
Davide Pesavento44deacc2014-02-19 10:48:07 +010050 * Ethernet frames as underlying transport mechanism
51 */
52class EthernetFace : public Face
53{
54public:
55 /**
Davide Pesavento7726ae52014-11-23 21:01:05 +010056 * @brief EthernetFace-related error
Davide Pesavento44deacc2014-02-19 10:48:07 +010057 */
58 struct Error : public Face::Error
59 {
60 Error(const std::string& what) : Face::Error(what) {}
61 };
62
63 EthernetFace(const shared_ptr<boost::asio::posix::stream_descriptor>& socket,
Davide Pesaventob499a602014-11-18 22:36:56 +010064 const NetworkInterfaceInfo& interface,
Davide Pesavento44deacc2014-02-19 10:48:07 +010065 const ethernet::Address& address);
66
Davide Pesavento66ff0982015-01-29 22:39:00 +010067 ~EthernetFace() DECL_OVERRIDE;
Davide Pesavento44deacc2014-02-19 10:48:07 +010068
69 /// send an Interest
Davide Pesavento66ff0982015-01-29 22:39:00 +010070 void
71 sendInterest(const Interest& interest) DECL_OVERRIDE;
Davide Pesavento44deacc2014-02-19 10:48:07 +010072
73 /// send a Data
Davide Pesavento66ff0982015-01-29 22:39:00 +010074 void
75 sendData(const Data& data) DECL_OVERRIDE;
Davide Pesavento44deacc2014-02-19 10:48:07 +010076
77 /**
Davide Pesavento7726ae52014-11-23 21:01:05 +010078 * @brief Closes the face
Davide Pesavento44deacc2014-02-19 10:48:07 +010079 *
Davide Pesavento7726ae52014-11-23 21:01:05 +010080 * This terminates all communication on the face and triggers the onFail() event.
Davide Pesavento44deacc2014-02-19 10:48:07 +010081 */
Davide Pesavento66ff0982015-01-29 22:39:00 +010082 void
83 close() DECL_OVERRIDE;
Davide Pesavento44deacc2014-02-19 10:48:07 +010084
85private:
Davide Pesavento7726ae52014-11-23 21:01:05 +010086 /**
87 * @brief Allocates and initializes a libpcap context for live capture
88 */
Davide Pesavento44deacc2014-02-19 10:48:07 +010089 void
90 pcapInit();
91
Davide Pesavento7726ae52014-11-23 21:01:05 +010092 /**
93 * @brief Installs a BPF filter on the receiving socket
94 *
95 * @param filterString string containing the source BPF program
96 */
Davide Pesavento44deacc2014-02-19 10:48:07 +010097 void
98 setPacketFilter(const char* filterString);
99
Davide Pesavento7726ae52014-11-23 21:01:05 +0100100 /**
101 * @brief Enables receiving frames addressed to our MAC multicast group
Davide Pesaventof8b41eb2014-12-26 19:14:06 +0100102 *
103 * @return true if successful, false otherwise
Davide Pesavento7726ae52014-11-23 21:01:05 +0100104 */
Davide Pesaventof8b41eb2014-12-26 19:14:06 +0100105 bool
Davide Pesavento10783f22014-03-15 04:40:01 +0100106 joinMulticastGroup();
107
Davide Pesavento7726ae52014-11-23 21:01:05 +0100108 /**
109 * @brief Sends the specified TLV block on the network wrapped in an Ethernet frame
110 */
Davide Pesavento10783f22014-03-15 04:40:01 +0100111 void
Davide Pesavento44deacc2014-02-19 10:48:07 +0100112 sendPacket(const ndn::Block& block);
113
Davide Pesavento7726ae52014-11-23 21:01:05 +0100114 /**
115 * @brief Receive callback
116 */
Davide Pesavento44deacc2014-02-19 10:48:07 +0100117 void
Davide Pesavento7726ae52014-11-23 21:01:05 +0100118 handleRead(const boost::system::error_code& error, size_t nBytesRead);
Davide Pesavento44deacc2014-02-19 10:48:07 +0100119
Davide Pesavento7726ae52014-11-23 21:01:05 +0100120PUBLIC_WITH_TESTS_ELSE_PRIVATE:
121 /**
122 * @brief Processes an incoming frame as captured by libpcap
123 *
124 * @param header pointer to capture metadata
125 * @param packet pointer to the received frame, including the link-layer header
126 */
127 void
128 processIncomingPacket(const pcap_pkthdr* header, const uint8_t* packet);
129
130private:
131 /**
132 * @brief Handles errors encountered by Boost.Asio on the receive path
133 */
Davide Pesavento44deacc2014-02-19 10:48:07 +0100134 void
135 processErrorCode(const boost::system::error_code& error);
136
Davide Pesavento7726ae52014-11-23 21:01:05 +0100137 /**
138 * @brief Returns the MTU of the underlying network interface
139 */
Davide Pesavento44deacc2014-02-19 10:48:07 +0100140 size_t
141 getInterfaceMtu() const;
142
143private:
Matteo Sammarco66df9742014-11-21 18:31:26 +0100144 struct Reassembler
145 {
146 unique_ptr<ndnlp::PartialMessageStore> pms;
Junxiao Shi1e46be32015-01-08 20:18:05 -0700147 scheduler::EventId expireEvent;
Matteo Sammarco66df9742014-11-21 18:31:26 +0100148 };
149
Davide Pesavento7726ae52014-11-23 21:01:05 +0100150 unique_ptr<pcap_t, void(*)(pcap_t*)> m_pcap;
Davide Pesavento44deacc2014-02-19 10:48:07 +0100151 shared_ptr<boost::asio::posix::stream_descriptor> m_socket;
Davide Pesavento7726ae52014-11-23 21:01:05 +0100152
Davide Pesavento10783f22014-03-15 04:40:01 +0100153#if defined(__linux__)
154 int m_interfaceIndex;
155#endif
Davide Pesaventob60cc122014-03-19 19:26:02 +0100156 std::string m_interfaceName;
157 ethernet::Address m_srcAddress;
Davide Pesavento44deacc2014-02-19 10:48:07 +0100158 ethernet::Address m_destAddress;
Matteo Sammarco66df9742014-11-21 18:31:26 +0100159
Davide Pesavento44deacc2014-02-19 10:48:07 +0100160 size_t m_interfaceMtu;
Matteo Sammarco66df9742014-11-21 18:31:26 +0100161 unique_ptr<ndnlp::Slicer> m_slicer;
162 std::unordered_map<ethernet::Address, Reassembler> m_reassemblers;
163 static const time::nanoseconds REASSEMBLER_LIFETIME;
Davide Pesavento9a090a02015-01-29 18:15:26 +0100164
165#ifdef _DEBUG
166 /// number of packets dropped by the kernel, as reported by libpcap
167 unsigned int m_nDropped;
168#endif
Davide Pesavento44deacc2014-02-19 10:48:07 +0100169};
170
171} // namespace nfd
172
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700173#endif // NFD_DAEMON_FACE_ETHERNET_FACE_HPP