blob: ce72a625ffe431c7abda37e54d3e483ad259adf5 [file] [log] [blame]
Davide Pesavento44deacc2014-02-19 10:48:07 +01001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Steve DiBenedettoef04f272014-06-04 14:28:31 -06003 * Copyright (c) 2014, 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
67 virtual
68 ~EthernetFace();
69
70 /// send an Interest
71 virtual void
72 sendInterest(const Interest& interest);
73
74 /// send a Data
75 virtual void
76 sendData(const Data& data);
77
78 /**
Davide Pesavento7726ae52014-11-23 21:01:05 +010079 * @brief Closes the face
Davide Pesavento44deacc2014-02-19 10:48:07 +010080 *
Davide Pesavento7726ae52014-11-23 21:01:05 +010081 * This terminates all communication on the face and triggers the onFail() event.
Davide Pesavento44deacc2014-02-19 10:48:07 +010082 */
83 virtual void
84 close();
85
86private:
Davide Pesavento7726ae52014-11-23 21:01:05 +010087 /**
88 * @brief Allocates and initializes a libpcap context for live capture
89 */
Davide Pesavento44deacc2014-02-19 10:48:07 +010090 void
91 pcapInit();
92
Davide Pesavento7726ae52014-11-23 21:01:05 +010093 /**
94 * @brief Installs a BPF filter on the receiving socket
95 *
96 * @param filterString string containing the source BPF program
97 */
Davide Pesavento44deacc2014-02-19 10:48:07 +010098 void
99 setPacketFilter(const char* filterString);
100
Davide Pesavento7726ae52014-11-23 21:01:05 +0100101 /**
102 * @brief Enables receiving frames addressed to our MAC multicast group
Davide Pesaventof8b41eb2014-12-26 19:14:06 +0100103 *
104 * @return true if successful, false otherwise
Davide Pesavento7726ae52014-11-23 21:01:05 +0100105 */
Davide Pesaventof8b41eb2014-12-26 19:14:06 +0100106 bool
Davide Pesavento10783f22014-03-15 04:40:01 +0100107 joinMulticastGroup();
108
Davide Pesavento7726ae52014-11-23 21:01:05 +0100109 /**
110 * @brief Sends the specified TLV block on the network wrapped in an Ethernet frame
111 */
Davide Pesavento10783f22014-03-15 04:40:01 +0100112 void
Davide Pesavento44deacc2014-02-19 10:48:07 +0100113 sendPacket(const ndn::Block& block);
114
Davide Pesavento7726ae52014-11-23 21:01:05 +0100115 /**
116 * @brief Receive callback
117 */
Davide Pesavento44deacc2014-02-19 10:48:07 +0100118 void
Davide Pesavento7726ae52014-11-23 21:01:05 +0100119 handleRead(const boost::system::error_code& error, size_t nBytesRead);
Davide Pesavento44deacc2014-02-19 10:48:07 +0100120
Davide Pesavento7726ae52014-11-23 21:01:05 +0100121PUBLIC_WITH_TESTS_ELSE_PRIVATE:
122 /**
123 * @brief Processes an incoming frame as captured by libpcap
124 *
125 * @param header pointer to capture metadata
126 * @param packet pointer to the received frame, including the link-layer header
127 */
128 void
129 processIncomingPacket(const pcap_pkthdr* header, const uint8_t* packet);
130
131private:
132 /**
133 * @brief Handles errors encountered by Boost.Asio on the receive path
134 */
Davide Pesavento44deacc2014-02-19 10:48:07 +0100135 void
136 processErrorCode(const boost::system::error_code& error);
137
Davide Pesavento7726ae52014-11-23 21:01:05 +0100138 /**
139 * @brief Returns the MTU of the underlying network interface
140 */
Davide Pesavento44deacc2014-02-19 10:48:07 +0100141 size_t
142 getInterfaceMtu() const;
143
144private:
Matteo Sammarco66df9742014-11-21 18:31:26 +0100145 struct Reassembler
146 {
147 unique_ptr<ndnlp::PartialMessageStore> pms;
148 EventId expireEvent;
149 };
150
Davide Pesavento7726ae52014-11-23 21:01:05 +0100151 unique_ptr<pcap_t, void(*)(pcap_t*)> m_pcap;
Davide Pesavento44deacc2014-02-19 10:48:07 +0100152 shared_ptr<boost::asio::posix::stream_descriptor> m_socket;
Davide Pesavento7726ae52014-11-23 21:01:05 +0100153
Davide Pesavento10783f22014-03-15 04:40:01 +0100154#if defined(__linux__)
155 int m_interfaceIndex;
156#endif
Davide Pesaventob60cc122014-03-19 19:26:02 +0100157 std::string m_interfaceName;
158 ethernet::Address m_srcAddress;
Davide Pesavento44deacc2014-02-19 10:48:07 +0100159 ethernet::Address m_destAddress;
Matteo Sammarco66df9742014-11-21 18:31:26 +0100160
Davide Pesavento44deacc2014-02-19 10:48:07 +0100161 size_t m_interfaceMtu;
Matteo Sammarco66df9742014-11-21 18:31:26 +0100162 unique_ptr<ndnlp::Slicer> m_slicer;
163 std::unordered_map<ethernet::Address, Reassembler> m_reassemblers;
164 static const time::nanoseconds REASSEMBLER_LIFETIME;
Davide Pesavento44deacc2014-02-19 10:48:07 +0100165};
166
167} // namespace nfd
168
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700169#endif // NFD_DAEMON_FACE_ETHERNET_FACE_HPP