face: make EthernetFace more robust against errors.

We now call .fail() instead of throwing an exception.

Also modernize the code with some C++11 features.
In particular, std::unique_ptr is now used to manage
the pcap instance.

Change-Id: I91200ff9ab64ddb2d86f082647043e42ca85f538
Refs: #1984
diff --git a/daemon/face/ethernet-face.hpp b/daemon/face/ethernet-face.hpp
index 0c673c3..1dd6593 100644
--- a/daemon/face/ethernet-face.hpp
+++ b/daemon/face/ethernet-face.hpp
@@ -26,7 +26,7 @@
 #ifndef NFD_DAEMON_FACE_ETHERNET_FACE_HPP
 #define NFD_DAEMON_FACE_ETHERNET_FACE_HPP
 
-#include "config.hpp"
+#include "common.hpp"
 #include "face.hpp"
 #include "core/network-interface.hpp"
 
@@ -37,18 +37,19 @@
 // forward declarations
 struct pcap;
 typedef pcap pcap_t;
+struct pcap_pkthdr;
 
 namespace nfd {
 
 /**
- * \brief Implementation of Face abstraction that uses raw
+ * @brief Implementation of Face abstraction that uses raw
  *        Ethernet frames as underlying transport mechanism
  */
 class EthernetFace : public Face
 {
 public:
   /**
-   * \brief EthernetFace-related error
+   * @brief EthernetFace-related error
    */
   struct Error : public Face::Error
   {
@@ -71,39 +72,73 @@
   sendData(const Data& data);
 
   /**
-   * \brief Close the face
+   * @brief Closes the face
    *
-   * This terminates all communication on the face and cause
-   * onFail() method event to be invoked
+   * This terminates all communication on the face and triggers the onFail() event.
    */
   virtual void
   close();
 
 private:
+  /**
+   * @brief Allocates and initializes a libpcap context for live capture
+   */
   void
   pcapInit();
 
+  /**
+   * @brief Installs a BPF filter on the receiving socket
+   *
+   * @param filterString string containing the source BPF program
+   */
   void
   setPacketFilter(const char* filterString);
 
+  /**
+   * @brief Enables receiving frames addressed to our MAC multicast group
+   */
   void
   joinMulticastGroup();
 
+  /**
+   * @brief Sends the specified TLV block on the network wrapped in an Ethernet frame
+   */
   void
   sendPacket(const ndn::Block& block);
 
+  /**
+   * @brief Receive callback
+   */
   void
-  handleRead(const boost::system::error_code& error,
-             size_t nBytesRead);
+  handleRead(const boost::system::error_code& error, size_t nBytesRead);
 
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  /**
+   * @brief Processes an incoming frame as captured by libpcap
+   *
+   * @param header pointer to capture metadata
+   * @param packet pointer to the received frame, including the link-layer header
+   */
+  void
+  processIncomingPacket(const pcap_pkthdr* header, const uint8_t* packet);
+
+private:
+  /**
+   * @brief Handles errors encountered by Boost.Asio on the receive path
+   */
   void
   processErrorCode(const boost::system::error_code& error);
 
+  /**
+   * @brief Returns the MTU of the underlying network interface
+   */
   size_t
   getInterfaceMtu() const;
 
 private:
+  unique_ptr<pcap_t, void(*)(pcap_t*)> m_pcap;
   shared_ptr<boost::asio::posix::stream_descriptor> m_socket;
+
 #if defined(__linux__)
   int m_interfaceIndex;
 #endif
@@ -111,7 +146,6 @@
   ethernet::Address m_srcAddress;
   ethernet::Address m_destAddress;
   size_t m_interfaceMtu;
-  pcap_t* m_pcap;
 };
 
 } // namespace nfd