blob: 2bbd78156f649eec5cbbcce3a65c0572dc7edd4d [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
Davide Pesavento292e5e12015-03-13 02:08:33 +010063 EthernetFace(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 Pesavento44deacc2014-02-19 10:48:07 +010067 /// send an Interest
Davide Pesavento66ff0982015-01-29 22:39:00 +010068 void
69 sendInterest(const Interest& interest) DECL_OVERRIDE;
Davide Pesavento44deacc2014-02-19 10:48:07 +010070
71 /// send a Data
Davide Pesavento66ff0982015-01-29 22:39:00 +010072 void
73 sendData(const Data& data) DECL_OVERRIDE;
Davide Pesavento44deacc2014-02-19 10:48:07 +010074
75 /**
Davide Pesavento7726ae52014-11-23 21:01:05 +010076 * @brief Closes the face
Davide Pesavento44deacc2014-02-19 10:48:07 +010077 *
Davide Pesavento7726ae52014-11-23 21:01:05 +010078 * This terminates all communication on the face and triggers the onFail() event.
Davide Pesavento44deacc2014-02-19 10:48:07 +010079 */
Davide Pesavento66ff0982015-01-29 22:39:00 +010080 void
81 close() DECL_OVERRIDE;
Davide Pesavento44deacc2014-02-19 10:48:07 +010082
83private:
Davide Pesavento7726ae52014-11-23 21:01:05 +010084 /**
85 * @brief Allocates and initializes a libpcap context for live capture
86 */
Davide Pesavento44deacc2014-02-19 10:48:07 +010087 void
88 pcapInit();
89
Davide Pesavento7726ae52014-11-23 21:01:05 +010090 /**
91 * @brief Installs a BPF filter on the receiving socket
92 *
93 * @param filterString string containing the source BPF program
94 */
Davide Pesavento44deacc2014-02-19 10:48:07 +010095 void
96 setPacketFilter(const char* filterString);
97
Davide Pesavento7726ae52014-11-23 21:01:05 +010098 /**
99 * @brief Enables receiving frames addressed to our MAC multicast group
Davide Pesaventof8b41eb2014-12-26 19:14:06 +0100100 *
101 * @return true if successful, false otherwise
Davide Pesavento7726ae52014-11-23 21:01:05 +0100102 */
Davide Pesaventof8b41eb2014-12-26 19:14:06 +0100103 bool
Davide Pesavento10783f22014-03-15 04:40:01 +0100104 joinMulticastGroup();
105
Davide Pesavento7726ae52014-11-23 21:01:05 +0100106 /**
107 * @brief Sends the specified TLV block on the network wrapped in an Ethernet frame
108 */
Davide Pesavento10783f22014-03-15 04:40:01 +0100109 void
Davide Pesavento44deacc2014-02-19 10:48:07 +0100110 sendPacket(const ndn::Block& block);
111
Davide Pesavento7726ae52014-11-23 21:01:05 +0100112 /**
113 * @brief Receive callback
114 */
Davide Pesavento44deacc2014-02-19 10:48:07 +0100115 void
Davide Pesavento7726ae52014-11-23 21:01:05 +0100116 handleRead(const boost::system::error_code& error, size_t nBytesRead);
Davide Pesavento44deacc2014-02-19 10:48:07 +0100117
Davide Pesavento7726ae52014-11-23 21:01:05 +0100118PUBLIC_WITH_TESTS_ELSE_PRIVATE:
119 /**
120 * @brief Processes an incoming frame as captured by libpcap
121 *
122 * @param header pointer to capture metadata
123 * @param packet pointer to the received frame, including the link-layer header
124 */
125 void
126 processIncomingPacket(const pcap_pkthdr* header, const uint8_t* packet);
127
128private:
129 /**
130 * @brief Handles errors encountered by Boost.Asio on the receive path
131 */
Davide Pesavento44deacc2014-02-19 10:48:07 +0100132 void
133 processErrorCode(const boost::system::error_code& error);
134
Davide Pesavento7726ae52014-11-23 21:01:05 +0100135 /**
136 * @brief Returns the MTU of the underlying network interface
137 */
Davide Pesavento44deacc2014-02-19 10:48:07 +0100138 size_t
Davide Pesavento292e5e12015-03-13 02:08:33 +0100139 getInterfaceMtu();
Davide Pesavento44deacc2014-02-19 10:48:07 +0100140
141private:
Matteo Sammarco66df9742014-11-21 18:31:26 +0100142 struct Reassembler
143 {
144 unique_ptr<ndnlp::PartialMessageStore> pms;
Junxiao Shi1e46be32015-01-08 20:18:05 -0700145 scheduler::EventId expireEvent;
Matteo Sammarco66df9742014-11-21 18:31:26 +0100146 };
147
Davide Pesavento7726ae52014-11-23 21:01:05 +0100148 unique_ptr<pcap_t, void(*)(pcap_t*)> m_pcap;
Davide Pesavento292e5e12015-03-13 02:08:33 +0100149 boost::asio::posix::stream_descriptor m_socket;
Davide Pesavento7726ae52014-11-23 21:01:05 +0100150
Davide Pesavento10783f22014-03-15 04:40:01 +0100151#if defined(__linux__)
152 int m_interfaceIndex;
153#endif
Davide Pesaventob60cc122014-03-19 19:26:02 +0100154 std::string m_interfaceName;
155 ethernet::Address m_srcAddress;
Davide Pesavento44deacc2014-02-19 10:48:07 +0100156 ethernet::Address m_destAddress;
Matteo Sammarco66df9742014-11-21 18:31:26 +0100157
Davide Pesavento44deacc2014-02-19 10:48:07 +0100158 size_t m_interfaceMtu;
Matteo Sammarco66df9742014-11-21 18:31:26 +0100159 unique_ptr<ndnlp::Slicer> m_slicer;
160 std::unordered_map<ethernet::Address, Reassembler> m_reassemblers;
161 static const time::nanoseconds REASSEMBLER_LIFETIME;
Davide Pesavento9a090a02015-01-29 18:15:26 +0100162
163#ifdef _DEBUG
164 /// number of packets dropped by the kernel, as reported by libpcap
165 unsigned int m_nDropped;
166#endif
Davide Pesavento44deacc2014-02-19 10:48:07 +0100167};
168
169} // namespace nfd
170
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700171#endif // NFD_DAEMON_FACE_ETHERNET_FACE_HPP