blob: 87e2238f647396fb46ed0a8454a72c5abe859921 [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
103 */
Davide Pesavento44deacc2014-02-19 10:48:07 +0100104 void
Davide Pesavento10783f22014-03-15 04:40:01 +0100105 joinMulticastGroup();
106
Davide Pesavento7726ae52014-11-23 21:01:05 +0100107 /**
108 * @brief Sends the specified TLV block on the network wrapped in an Ethernet frame
109 */
Davide Pesavento10783f22014-03-15 04:40:01 +0100110 void
Davide Pesavento44deacc2014-02-19 10:48:07 +0100111 sendPacket(const ndn::Block& block);
112
Davide Pesavento7726ae52014-11-23 21:01:05 +0100113 /**
114 * @brief Receive callback
115 */
Davide Pesavento44deacc2014-02-19 10:48:07 +0100116 void
Davide Pesavento7726ae52014-11-23 21:01:05 +0100117 handleRead(const boost::system::error_code& error, size_t nBytesRead);
Davide Pesavento44deacc2014-02-19 10:48:07 +0100118
Davide Pesavento7726ae52014-11-23 21:01:05 +0100119PUBLIC_WITH_TESTS_ELSE_PRIVATE:
120 /**
121 * @brief Processes an incoming frame as captured by libpcap
122 *
123 * @param header pointer to capture metadata
124 * @param packet pointer to the received frame, including the link-layer header
125 */
126 void
127 processIncomingPacket(const pcap_pkthdr* header, const uint8_t* packet);
128
129private:
130 /**
131 * @brief Handles errors encountered by Boost.Asio on the receive path
132 */
Davide Pesavento44deacc2014-02-19 10:48:07 +0100133 void
134 processErrorCode(const boost::system::error_code& error);
135
Davide Pesavento7726ae52014-11-23 21:01:05 +0100136 /**
137 * @brief Returns the MTU of the underlying network interface
138 */
Davide Pesavento44deacc2014-02-19 10:48:07 +0100139 size_t
140 getInterfaceMtu() const;
141
142private:
Matteo Sammarco66df9742014-11-21 18:31:26 +0100143 struct Reassembler
144 {
145 unique_ptr<ndnlp::PartialMessageStore> pms;
146 EventId expireEvent;
147 };
148
Davide Pesavento7726ae52014-11-23 21:01:05 +0100149 unique_ptr<pcap_t, void(*)(pcap_t*)> m_pcap;
Davide Pesavento44deacc2014-02-19 10:48:07 +0100150 shared_ptr<boost::asio::posix::stream_descriptor> m_socket;
Davide Pesavento7726ae52014-11-23 21:01:05 +0100151
Davide Pesavento10783f22014-03-15 04:40:01 +0100152#if defined(__linux__)
153 int m_interfaceIndex;
154#endif
Davide Pesaventob60cc122014-03-19 19:26:02 +0100155 std::string m_interfaceName;
156 ethernet::Address m_srcAddress;
Davide Pesavento44deacc2014-02-19 10:48:07 +0100157 ethernet::Address m_destAddress;
Matteo Sammarco66df9742014-11-21 18:31:26 +0100158
Davide Pesavento44deacc2014-02-19 10:48:07 +0100159 size_t m_interfaceMtu;
Matteo Sammarco66df9742014-11-21 18:31:26 +0100160 unique_ptr<ndnlp::Slicer> m_slicer;
161 std::unordered_map<ethernet::Address, Reassembler> m_reassemblers;
162 static const time::nanoseconds REASSEMBLER_LIFETIME;
Davide Pesavento44deacc2014-02-19 10:48:07 +0100163};
164
165} // namespace nfd
166
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700167#endif // NFD_DAEMON_FACE_ETHERNET_FACE_HPP