diff --git a/src/net/detail/link-type-helper-osx.mm b/src/net/detail/link-type-helper-osx.mm
new file mode 100644
index 0000000..c45fa04
--- /dev/null
+++ b/src/net/detail/link-type-helper-osx.mm
@@ -0,0 +1,65 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2017 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#include "link-type-helper.hpp"
+
+#ifndef NDN_CXX_HAVE_OSX_FRAMEWORKS
+#error "This file should not be compiled ..."
+#endif
+
+#import <Foundation/Foundation.h>
+#import <CoreWLAN/CoreWLAN.h>
+#import <CoreWLAN/CWInterface.h>
+#import <CoreWLAN/CWWiFiClient.h>
+
+namespace ndn {
+namespace net {
+namespace detail {
+
+ndn::nfd::LinkType
+getLinkType(const std::string& ifName)
+{
+  @autoreleasepool {
+    NSString* interfaceName = [NSString stringWithCString:ifName.c_str()
+                                                 encoding:[NSString defaultCStringEncoding]];
+
+    CWWiFiClient* wifiInterface = [CWWiFiClient sharedWiFiClient];
+    if (wifiInterface == nullptr) {
+      return nfd::LINK_TYPE_NONE;
+    }
+
+    CWInterface* airport = [wifiInterface interfaceWithName:interfaceName];
+    if (airport == nullptr) {
+      return nfd::LINK_TYPE_NONE;
+    }
+
+    if ([airport interfaceMode] == kCWInterfaceModeIBSS) {
+      return nfd::LINK_TYPE_AD_HOC;
+    }
+    else {
+      return nfd::LINK_TYPE_MULTI_ACCESS;
+    }
+  }
+}
+
+} // namespace detail
+} // namespace net
+} // namespace ndn
diff --git a/src/net/detail/link-type-helper.cpp b/src/net/detail/link-type-helper.cpp
new file mode 100644
index 0000000..36d51de
--- /dev/null
+++ b/src/net/detail/link-type-helper.cpp
@@ -0,0 +1,43 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2017 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#include "link-type-helper.hpp"
+#include "ndn-cxx-config.hpp"
+
+#ifdef NDN_CXX_HAVE_OSX_FRAMEWORKS
+// implemented in link-type-helper-osx.mm
+#else
+
+namespace ndn {
+namespace net {
+namespace detail {
+
+ndn::nfd::LinkType
+getLinkType(const std::string& ifName)
+{
+  return nfd::LINK_TYPE_NONE;
+}
+
+} // namespace detail
+} // namespace net
+} // namespace ndn
+
+#endif // NDN_CXX_HAVE_OSX_FRAMEWORKS
diff --git a/src/net/detail/link-type-helper.hpp b/src/net/detail/link-type-helper.hpp
new file mode 100644
index 0000000..9512f31
--- /dev/null
+++ b/src/net/detail/link-type-helper.hpp
@@ -0,0 +1,41 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2017 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#ifndef NDN_NET_DETAIL_LINK_TYPE_HELPER_HPP
+#define NDN_NET_DETAIL_LINK_TYPE_HELPER_HPP
+
+#include "../../encoding/nfd-constants.hpp"
+
+namespace ndn {
+namespace net {
+namespace detail {
+
+/**
+ * @brief Obtain information about WiFi link type
+ */
+ndn::nfd::LinkType
+getLinkType(const std::string& ifName);
+
+} // namespace detail
+} // namespace net
+} // namespace ndn
+
+#endif // NDN_NET_DETAIL_LINK_TYPE_HELPER_HPP
diff --git a/src/net/detail/linux-if-constants.cpp b/src/net/detail/linux-if-constants.cpp
new file mode 100644
index 0000000..dbcf54b
--- /dev/null
+++ b/src/net/detail/linux-if-constants.cpp
@@ -0,0 +1,51 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2017 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Davide Pesavento <davide.pesavento@lip6.fr>
+ */
+
+#ifdef __linux__
+
+#include "linux-if-constants.hpp"
+
+#include <sys/socket.h>
+#include <linux/if.h>
+
+namespace ndn {
+namespace net {
+namespace linux_if {
+
+const uint32_t FLAG_LOWER_UP = IFF_LOWER_UP;
+const uint32_t FLAG_DORMANT  = IFF_DORMANT;
+const uint32_t FLAG_ECHO     = IFF_ECHO;
+
+const uint8_t OPER_STATE_UNKNOWN        = IF_OPER_UNKNOWN;
+const uint8_t OPER_STATE_NOTPRESENT     = IF_OPER_NOTPRESENT;
+const uint8_t OPER_STATE_DOWN           = IF_OPER_DOWN;
+const uint8_t OPER_STATE_LOWERLAYERDOWN = IF_OPER_LOWERLAYERDOWN;
+const uint8_t OPER_STATE_TESTING        = IF_OPER_TESTING;
+const uint8_t OPER_STATE_DORMANT        = IF_OPER_DORMANT;
+const uint8_t OPER_STATE_UP             = IF_OPER_UP;
+
+} // namespace linux_if
+} // namespace net
+} // namespace ndn
+
+#endif // __linux__
diff --git a/src/net/detail/linux-if-constants.hpp b/src/net/detail/linux-if-constants.hpp
new file mode 100644
index 0000000..0670e70
--- /dev/null
+++ b/src/net/detail/linux-if-constants.hpp
@@ -0,0 +1,58 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2017 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Davide Pesavento <davide.pesavento@lip6.fr>
+ */
+
+#ifndef NDN_NET_LINUX_IF_CONSTANTS_HPP
+#define NDN_NET_LINUX_IF_CONSTANTS_HPP
+#ifdef __linux__
+
+#include <cstdint>
+
+namespace ndn {
+namespace net {
+namespace linux_if {
+
+// linux/if.h and net/if.h cannot be (directly or indirectly) included in the
+// same translation unit because they contain duplicate declarations, therefore
+// we have to resort to this workaround when we need to include both linux/if.h
+// and any other headers that pull in net/if.h (e.g. boost/asio.hpp)
+
+// net_device_flags missing from <net/if.h>
+extern const uint32_t FLAG_LOWER_UP;
+extern const uint32_t FLAG_DORMANT;
+extern const uint32_t FLAG_ECHO;
+
+// RFC 2863 operational status
+extern const uint8_t OPER_STATE_UNKNOWN;
+extern const uint8_t OPER_STATE_NOTPRESENT;
+extern const uint8_t OPER_STATE_DOWN;
+extern const uint8_t OPER_STATE_LOWERLAYERDOWN;
+extern const uint8_t OPER_STATE_TESTING;
+extern const uint8_t OPER_STATE_DORMANT;
+extern const uint8_t OPER_STATE_UP;
+
+} // namespace linux_if
+} // namespace net
+} // namespace ndn
+
+#endif // __linux__
+#endif // NDN_NET_LINUX_IF_CONSTANTS_HPP
diff --git a/src/net/detail/network-monitor-impl-noop.hpp b/src/net/detail/network-monitor-impl-noop.hpp
new file mode 100644
index 0000000..f0c5fb0
--- /dev/null
+++ b/src/net/detail/network-monitor-impl-noop.hpp
@@ -0,0 +1,61 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2017 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Davide Pesavento <davide.pesavento@lip6.fr>
+ */
+
+#ifndef NDN_NET_NETWORK_MONITOR_IMPL_NOOP_HPP
+#define NDN_NET_NETWORK_MONITOR_IMPL_NOOP_HPP
+
+#include "../network-monitor.hpp"
+
+namespace ndn {
+namespace net {
+
+class NetworkMonitor::Impl
+{
+public:
+  Impl(NetworkMonitor& nm, boost::asio::io_service& io)
+  {
+  }
+
+  uint32_t
+  getCapabilities() const
+  {
+    return NetworkMonitor::CAP_NONE;
+  }
+
+  shared_ptr<NetworkInterface>
+  getNetworkInterface(const std::string&) const
+  {
+    return {};
+  }
+
+  std::vector<shared_ptr<NetworkInterface>>
+  listNetworkInterfaces() const
+  {
+    return {};
+  }
+};
+
+} // namespace net
+} // namespace ndn
+
+#endif // NDN_NET_NETWORK_MONITOR_IMPL_NOOP_HPP
diff --git a/src/net/detail/network-monitor-impl-osx.cpp b/src/net/detail/network-monitor-impl-osx.cpp
new file mode 100644
index 0000000..97f3e7c
--- /dev/null
+++ b/src/net/detail/network-monitor-impl-osx.cpp
@@ -0,0 +1,453 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2017 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ *
+ * Parts of this implementation is based on daemondo command of MacPorts
+ * (https://www.macports.org/):
+ *
+ *    Copyright (c) 2005-2007 James Berry <jberry@macports.org>
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *   3. Neither the name of The MacPorts Project nor the names of its contributors
+ *      may be used to endorse or promote products derived from this software
+ *      without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ *   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *   POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "ndn-cxx-config.hpp"
+
+#include "network-monitor-impl-osx.hpp"
+#include "../../name.hpp"
+#include "../../util/logger.hpp"
+#include "../network-address.hpp"
+
+#include <ifaddrs.h>       // for getifaddrs()
+#include <arpa/inet.h>     // for inet_ntop()
+#include <netinet/in.h>    // for struct sockaddr_in{,6}
+#include <net/if_dl.h>     // for struct sockaddr_dl
+#include <net/if_types.h>  // for IFT_* constants
+
+#include <boost/asio.hpp>
+
+namespace ndn {
+namespace net {
+
+NDN_LOG_INIT(ndn.NetworkMonitor);
+
+NetworkMonitor::Impl::Impl(NetworkMonitor& nm, boost::asio::io_service& io)
+  : m_nm(nm)
+  , m_scheduler(io)
+  , m_cfLoopEvent(m_scheduler)
+  , m_context{0, this, nullptr, nullptr, nullptr}
+  , m_scStore(SCDynamicStoreCreate(nullptr, CFSTR("net.named-data.ndn-cxx.NetworkMonitor"),
+                                   &Impl::onConfigChanged, &m_context))
+  , m_loopSource(SCDynamicStoreCreateRunLoopSource(nullptr, m_scStore.get(), 0))
+  , m_nullUdpSocket(io, boost::asio::ip::udp::v4())
+
+{
+  scheduleCfLoop();
+
+  // Notifications from Darwin Notify Center:
+  //
+  // com.apple.system.config.network_change
+  //
+  CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),
+                                  static_cast<void*>(this),
+                                  &Impl::afterNotificationCenterEvent,
+                                  CFSTR("com.apple.system.config.network_change"),
+                                  nullptr, // object to observe
+                                  CFNotificationSuspensionBehaviorDeliverImmediately);
+
+  io.post([this] { enumerateInterfaces(); });
+
+  CFRunLoopAddSource(CFRunLoopGetCurrent(), m_loopSource.get(), kCFRunLoopDefaultMode);
+
+  // Notifications from SystemConfiguration:
+  //
+  // State:/Network/Interface/.*/Link
+  // State:/Network/Interface/.*/IPv4
+  // State:/Network/Interface/.*/IPv6
+  // State:/Network/Global/DNS
+  // State:/Network/Global/IPv4
+  //
+  auto patterns = CFArrayCreateMutable(nullptr, 0, &kCFTypeArrayCallBacks);
+  CFArrayAppendValue(patterns, CFSTR("State:/Network/Interface/.*/Link"));
+  CFArrayAppendValue(patterns, CFSTR("State:/Network/Interface/.*/IPv4"));
+  CFArrayAppendValue(patterns, CFSTR("State:/Network/Interface/.*/IPv6"));
+  // CFArrayAppendValue(patterns, CFSTR("State:/Network/Global/DNS"));
+  // CFArrayAppendValue(patterns, CFSTR("State:/Network/Global/IPv4"));
+
+  SCDynamicStoreSetNotificationKeys(m_scStore.get(), nullptr, patterns);
+}
+
+NetworkMonitor::Impl::~Impl()
+{
+  CFRunLoopRemoveSource(CFRunLoopGetCurrent(), m_loopSource.get(), kCFRunLoopDefaultMode);
+
+  CFNotificationCenterRemoveEveryObserver(CFNotificationCenterGetDarwinNotifyCenter(),
+                                          static_cast<void*>(this));
+}
+
+shared_ptr<NetworkInterface>
+NetworkMonitor::Impl::getNetworkInterface(const std::string& ifname) const
+{
+  auto it = m_interfaces.find(ifname);
+  if (it != m_interfaces.end()) {
+    return it->second;
+  }
+  else {
+    return nullptr;
+  }
+}
+
+std::vector<shared_ptr<NetworkInterface>>
+NetworkMonitor::Impl::listNetworkInterfaces() const
+{
+  std::vector<shared_ptr<NetworkInterface>> v;
+  v.reserve(m_interfaces.size());
+
+  for (const auto& e : m_interfaces) {
+    v.push_back(e.second);
+  }
+  return v;
+}
+
+void
+NetworkMonitor::Impl::afterNotificationCenterEvent(CFNotificationCenterRef center,
+                                                   void* observer,
+                                                   CFStringRef name,
+                                                   const void* object,
+                                                   CFDictionaryRef userInfo)
+{
+  static_cast<Impl*>(observer)->m_nm.onNetworkStateChanged();
+}
+
+void
+NetworkMonitor::Impl::scheduleCfLoop()
+{
+  // poll each second for new events
+  m_cfLoopEvent = m_scheduler.scheduleEvent(time::seconds(1), bind(&Impl::pollCfLoop, this));
+}
+
+void
+NetworkMonitor::Impl::pollCfLoop()
+{
+  // this should dispatch ready events and exit
+  CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true);
+
+  scheduleCfLoop();
+}
+
+void
+NetworkMonitor::Impl::addNewInterface(const std::string& ifName)
+{
+  shared_ptr<NetworkInterface> interface(new NetworkInterface);
+
+  interface->setName(ifName);
+  interface->setState(getInterfaceState(interface->getName()));
+  updateInterfaceInfo(*interface);
+  if (interface->getType() == InterfaceType::UNKNOWN) {
+    NDN_LOG_DEBUG("ignoring " << ifName << " because it has unhandled interface type");
+    return;
+  }
+
+  NDN_LOG_DEBUG("adding interface " << interface->getName());
+  m_interfaces.insert(make_pair(interface->getName(), interface));
+  m_nm.onInterfaceAdded(interface);
+}
+
+void
+NetworkMonitor::Impl::enumerateInterfaces()
+{
+  for (const auto& ifName : getInterfaceNames()) {
+    addNewInterface(ifName);
+  }
+  m_nm.onEnumerationCompleted();
+}
+
+static std::string
+convertToStdString(CFStringRef cfString)
+{
+  const char* cStr = CFStringGetCStringPtr(cfString, kCFStringEncodingASCII);
+  if (cStr != nullptr) {
+    return cStr;
+  }
+
+  size_t stringSize =  CFStringGetLength(cfString);
+  char* buffer = new char[stringSize + 1];
+  CFStringGetCString(cfString, buffer, sizeof(buffer), kCFStringEncodingASCII);
+  std::string retval = buffer;
+  delete [] buffer;
+  return retval;
+}
+
+std::set<std::string>
+NetworkMonitor::Impl::getInterfaceNames()
+{
+  CFReleaser<CFDictionaryRef> dict = (CFDictionaryRef)SCDynamicStoreCopyValue(m_scStore.get(), CFSTR("State:/Network/Interface"));
+  CFArrayRef interfaces = (CFArrayRef)CFDictionaryGetValue(dict.get(), CFSTR("Interfaces"));
+
+  std::set<std::string> ifNames;
+  size_t count = CFArrayGetCount(interfaces);
+  for (size_t i = 0; i != count; ++i) {
+    auto ifName = (CFStringRef)CFArrayGetValueAtIndex(interfaces, i);
+    ifNames.insert(convertToStdString(ifName));
+  }
+  return ifNames;
+}
+
+InterfaceState
+NetworkMonitor::Impl::getInterfaceState(const std::string& ifName)
+{
+  CFReleaser<CFStringRef> linkName = CFStringCreateWithCString(nullptr,
+                                                               ("State:/Network/Interface/" + ifName + "/Link").c_str(),
+                                                               kCFStringEncodingASCII);
+
+  CFReleaser<CFDictionaryRef> dict = (CFDictionaryRef)SCDynamicStoreCopyValue(m_scStore.get(), linkName.get());
+  if (dict.get() == nullptr) {
+    return InterfaceState::UNKNOWN;
+  }
+
+  CFBooleanRef isActive = (CFBooleanRef)CFDictionaryGetValue(dict.get(), CFSTR("Active"));
+  if (isActive == nullptr) {
+    return InterfaceState::UNKNOWN;
+  }
+
+  return CFBooleanGetValue(isActive) ? InterfaceState::RUNNING : InterfaceState::DOWN;
+}
+
+void
+NetworkMonitor::Impl::updateInterfaceInfo(NetworkInterface& netif)
+{
+  ifaddrs* ifa_list = nullptr;
+  if (::getifaddrs(&ifa_list) < 0) {
+    BOOST_THROW_EXCEPTION(Error(std::string("getifaddrs() failed: ") + strerror(errno)));
+  }
+
+  for (ifaddrs* ifa = ifa_list; ifa != nullptr; ifa = ifa->ifa_next) {
+    if (ifa->ifa_name != netif.getName()) {
+      continue;
+    }
+
+    netif.setFlags(ifa->ifa_flags);
+    netif.setMtu(getInterfaceMtu(netif.getName()));
+
+    if (ifa->ifa_addr == nullptr)
+      continue;
+
+    NetworkAddress address;
+
+    switch (ifa->ifa_addr->sa_family) {
+      case AF_INET: {
+        address.m_family = AddressFamily::V4;
+
+        const sockaddr_in* sin = reinterpret_cast<sockaddr_in*>(ifa->ifa_addr);
+        boost::asio::ip::address_v4::bytes_type bytes;
+        std::copy_n(reinterpret_cast<const unsigned char*>(&sin->sin_addr), bytes.size(), bytes.begin());
+        address.m_ip = boost::asio::ip::address_v4(bytes);
+
+        const sockaddr_in* sinMask = reinterpret_cast<sockaddr_in*>(ifa->ifa_netmask);
+        std::copy_n(reinterpret_cast<const unsigned char*>(&sinMask->sin_addr), bytes.size(), bytes.begin());
+        uint8_t mask = 0;
+        for (auto byte : bytes) {
+          while (byte != 0) {
+            ++mask;
+            byte <<= 1;
+          }
+        }
+        address.m_prefixLength = mask;
+        break;
+      }
+
+      case AF_INET6: {
+        address.m_family = AddressFamily::V6;
+
+        const sockaddr_in6* sin6 = reinterpret_cast<sockaddr_in6*>(ifa->ifa_addr);
+        boost::asio::ip::address_v6::bytes_type bytes;
+        std::copy_n(reinterpret_cast<const unsigned char*>(&sin6->sin6_addr), bytes.size(), bytes.begin());
+        address.m_ip = boost::asio::ip::address_v6(bytes);
+
+        const sockaddr_in6* sinMask = reinterpret_cast<sockaddr_in6*>(ifa->ifa_netmask);
+        std::copy_n(reinterpret_cast<const unsigned char*>(&sinMask->sin6_addr), bytes.size(), bytes.begin());
+        uint8_t mask = 0;
+        for (auto byte : bytes) {
+          while (byte != 0) {
+            ++mask;
+            byte <<= 1;
+          }
+        }
+        address.m_prefixLength = mask;
+        break;
+      }
+
+      case AF_LINK: {
+        const sockaddr_dl* sdl = reinterpret_cast<sockaddr_dl*>(ifa->ifa_addr);
+        netif.setIndex(sdl->sdl_index);
+        if (sdl->sdl_type == IFT_ETHER && sdl->sdl_alen == ethernet::ADDR_LEN) {
+          netif.setType(InterfaceType::ETHERNET);
+          netif.setEthernetAddress(ethernet::Address(reinterpret_cast<uint8_t*>(LLADDR(sdl))));
+          NDN_LOG_TRACE(netif.getName() << ": set Ethernet address " << netif.getEthernetAddress());
+        }
+        else if (sdl->sdl_type == IFT_LOOP) {
+          netif.setType(InterfaceType::LOOPBACK);
+        }
+        else {
+          netif.setType(InterfaceType::UNKNOWN);
+        }
+        break;
+      }
+
+      default:
+        continue;
+    }
+
+    if (netif.canBroadcast() && ifa->ifa_broadaddr != nullptr) {
+      const sockaddr_in* sin = reinterpret_cast<sockaddr_in*>(ifa->ifa_broadaddr);
+      boost::asio::ip::address_v4::bytes_type bytes;
+      std::copy_n(reinterpret_cast<const unsigned char*>(&sin->sin_addr), bytes.size(), bytes.begin());
+      address.m_broadcast = boost::asio::ip::address_v4(bytes);
+      NDN_LOG_TRACE(netif.getName() << ": set IPv4 broadcast address " << address.m_broadcast);
+    }
+
+    if (netif.canBroadcast()) {
+      netif.setEthernetBroadcastAddress(ethernet::getBroadcastAddress());
+    }
+
+    netif.addNetworkAddress(address);
+  }
+
+  ::freeifaddrs(ifa_list);
+}
+
+size_t
+NetworkMonitor::Impl::getInterfaceMtu(const std::string& ifName)
+{
+  ifreq ifr{};
+  std::strncpy(ifr.ifr_name, ifName.c_str(), sizeof(ifr.ifr_name) - 1);
+
+  if (::ioctl(m_nullUdpSocket.native_handle(), SIOCGIFMTU, &ifr) == 0) {
+    return static_cast<size_t>(ifr.ifr_mtu);
+  }
+
+  NDN_LOG_WARN("Failed to get interface MTU: " << std::strerror(errno));
+  return ethernet::MAX_DATA_LEN;
+}
+
+void
+NetworkMonitor::Impl::onConfigChanged(SCDynamicStoreRef m_scStore, CFArrayRef changedKeys, void* context)
+{
+  static_cast<Impl*>(context)->onConfigChanged(changedKeys);
+}
+
+void
+NetworkMonitor::Impl::onConfigChanged(CFArrayRef changedKeys)
+{
+  size_t count = CFArrayGetCount(changedKeys);
+  for (size_t i = 0; i != count; ++i) {
+    std::string keyName = convertToStdString((CFStringRef)CFArrayGetValueAtIndex(changedKeys, i));
+    Name key(keyName);
+    std::string ifName = key.at(-2).toUri();
+
+    auto ifIt = m_interfaces.find(ifName);
+    if (ifIt == m_interfaces.end()) {
+      addNewInterface(ifName);
+      return;
+    }
+
+    NetworkInterface& netif = *ifIt->second;
+
+    auto removeInterface = [&] {
+      NDN_LOG_DEBUG("removing interface " << ifName);
+      shared_ptr<NetworkInterface> removedInterface = ifIt->second;
+      m_interfaces.erase(ifIt);
+      m_nm.onInterfaceRemoved(removedInterface);
+    };
+
+    if (key.at(-1).toUri() == "Link") {
+      auto newState = getInterfaceState(ifName);
+
+      if (newState == InterfaceState::UNKNOWN) {
+        // check if it is really unknown or interface removed
+        if (getInterfaceNames().count(ifName) == 0) {
+          // newState = InterfaceState::DOWN;
+          removeInterface();
+          return;
+        }
+      }
+
+      NDN_LOG_TRACE("Status of " << ifName << " changed from " << netif.getState() << " to " << newState);
+      netif.setState(newState);
+    }
+
+    if (key.at(-1).toUri() == "IPv4" || key.at(-1).toUri() == "IPv6") {
+      NetworkInterface updatedInterface;
+      updatedInterface.setName(ifName);
+      updateInterfaceInfo(updatedInterface);
+      if (updatedInterface.getType() == InterfaceType::UNKNOWN) {
+        // somehow, type of interface changed to unknown
+        NDN_LOG_DEBUG("Removing " << ifName << " because it changed to unhandled interface type");
+        removeInterface();
+        return;
+      }
+
+      const auto& newAddrs = updatedInterface.getNetworkAddresses();
+      const auto& oldAddrs = netif.getNetworkAddresses();
+
+      std::set<NetworkAddress> added;
+      std::set<NetworkAddress> removed;
+
+      std::set_difference(newAddrs.begin(), newAddrs.end(),
+                          oldAddrs.begin(), oldAddrs.end(), std::inserter(added, added.end()));
+
+      std::set_difference(oldAddrs.begin(), oldAddrs.end(),
+                          newAddrs.begin(), newAddrs.end(), std::inserter(removed, removed.end()));
+
+      for (const auto& addr : removed) {
+        netif.removeNetworkAddress(addr);
+      }
+
+      for (const auto& addr : added) {
+        netif.addNetworkAddress(addr);
+      }
+    }
+  }
+}
+
+} // namespace net
+} // namespace ndn
diff --git a/src/net/detail/network-monitor-impl-osx.hpp b/src/net/detail/network-monitor-impl-osx.hpp
new file mode 100644
index 0000000..3aac23f
--- /dev/null
+++ b/src/net/detail/network-monitor-impl-osx.hpp
@@ -0,0 +1,120 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2017 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#ifndef NDN_NET_NETWORK_MONITOR_IMPL_OSX_HPP
+#define NDN_NET_NETWORK_MONITOR_IMPL_OSX_HPP
+
+#include "ndn-cxx-config.hpp"
+#include "../network-monitor.hpp"
+
+#ifndef NDN_CXX_HAVE_OSX_FRAMEWORKS
+#error "This file should not be compiled ..."
+#endif
+
+#include "../network-interface.hpp"
+#include "../../security/tpm/helper-osx.hpp"
+#include "../../util/scheduler.hpp"
+#include "../../util/scheduler-scoped-event-id.hpp"
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+
+#include <boost/asio/ip/udp.hpp>
+
+namespace ndn {
+namespace net {
+
+class NetworkMonitor::Impl
+{
+public:
+  Impl(NetworkMonitor& nm, boost::asio::io_service& io);
+
+  ~Impl();
+
+  uint32_t
+  getCapabilities() const
+  {
+    return NetworkMonitor::CAP_ENUM | NetworkMonitor::CAP_IF_ADD_REMOVE |
+      NetworkMonitor::CAP_STATE_CHANGE | NetworkMonitor::CAP_ADDR_ADD_REMOVE;
+  }
+
+  shared_ptr<NetworkInterface>
+  getNetworkInterface(const std::string& ifname) const;
+
+  std::vector<shared_ptr<NetworkInterface>>
+  listNetworkInterfaces() const;
+
+  static void
+  afterNotificationCenterEvent(CFNotificationCenterRef center,
+                               void* observer,
+                               CFStringRef name,
+                               const void* object,
+                               CFDictionaryRef userInfo);
+
+private:
+  void
+  scheduleCfLoop();
+
+  void
+  pollCfLoop();
+
+  void
+  addNewInterface(const std::string& ifName);
+
+  void
+  enumerateInterfaces();
+
+  std::set<std::string>
+  getInterfaceNames();
+
+  InterfaceState
+  getInterfaceState(const std::string& ifName);
+
+  void
+  updateInterfaceInfo(NetworkInterface& netif);
+
+  size_t
+  getInterfaceMtu(const std::string& ifName);
+
+  static void
+  onConfigChanged(SCDynamicStoreRef store, CFArrayRef changedKeys, void* context);
+
+  void
+  onConfigChanged(CFArrayRef changedKeys);
+
+private:
+  NetworkMonitor& m_nm;
+  std::map<std::string /*ifname*/, shared_ptr<NetworkInterface>> m_interfaces; ///< interface map
+
+  util::Scheduler m_scheduler;
+  util::scheduler::ScopedEventId m_cfLoopEvent;
+
+  SCDynamicStoreContext m_context;
+  CFReleaser<SCDynamicStoreRef> m_scStore;
+  CFReleaser<CFRunLoopSourceRef> m_loopSource;
+
+  boost::asio::ip::udp::socket m_nullUdpSocket;
+};
+
+} // namespace net
+} // namespace ndn
+
+#endif // NDN_NET_NETWORK_MONITOR_IMPL_OSX_HPP
diff --git a/src/net/detail/network-monitor-impl-rtnl.cpp b/src/net/detail/network-monitor-impl-rtnl.cpp
new file mode 100644
index 0000000..1a05986
--- /dev/null
+++ b/src/net/detail/network-monitor-impl-rtnl.cpp
@@ -0,0 +1,510 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2017 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Davide Pesavento <davide.pesavento@lip6.fr>
+ */
+
+#include "network-monitor-impl-rtnl.hpp"
+#include "linux-if-constants.hpp"
+#include "../network-address.hpp"
+#include "../network-interface.hpp"
+#include "../../util/logger.hpp"
+#include "../../util/time.hpp"
+
+#include <boost/asio/write.hpp>
+
+#include <cerrno>
+#include <cstdlib>
+#include <net/if_arp.h>
+#include <sys/socket.h>
+
+NDN_LOG_INIT(ndn.NetworkMonitor);
+
+namespace ndn {
+namespace net {
+
+NetworkMonitor::Impl::Impl(NetworkMonitor& nm, boost::asio::io_service& io)
+  : m_nm(nm)
+  , m_socket(make_shared<boost::asio::posix::stream_descriptor>(io))
+  , m_pid(0)
+  , m_sequenceNo(static_cast<uint32_t>(time::system_clock::now().time_since_epoch().count()))
+  , m_isEnumeratingLinks(false)
+  , m_isEnumeratingAddresses(false)
+{
+  initSocket();
+  asyncRead();
+
+  NDN_LOG_TRACE("enumerating links");
+  sendDumpRequest(RTM_GETLINK);
+  m_isEnumeratingLinks = true;
+}
+
+NetworkMonitor::Impl::~Impl()
+{
+  boost::system::error_code error;
+  m_socket->close(error);
+}
+
+shared_ptr<NetworkInterface>
+NetworkMonitor::Impl::getNetworkInterface(const std::string& ifname) const
+{
+  for (const auto& e : m_interfaces) {
+    if (e.second->getName() == ifname)
+      return e.second;
+  }
+  return nullptr;
+}
+
+std::vector<shared_ptr<NetworkInterface>>
+NetworkMonitor::Impl::listNetworkInterfaces() const
+{
+  std::vector<shared_ptr<NetworkInterface>> v;
+  v.reserve(m_interfaces.size());
+
+  for (const auto& e : m_interfaces) {
+    v.push_back(e.second);
+  }
+  return v;
+}
+
+bool
+NetworkMonitor::Impl::isEnumerating() const
+{
+  return m_isEnumeratingLinks || m_isEnumeratingAddresses;
+}
+
+void
+NetworkMonitor::Impl::initSocket()
+{
+  NDN_LOG_TRACE("creating netlink socket");
+
+  int fd = ::socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);
+  if (fd < 0) {
+    BOOST_THROW_EXCEPTION(Error(std::string("Cannot create netlink socket (") +
+                                std::strerror(errno) + ")"));
+  }
+  m_socket->assign(fd);
+
+  sockaddr_nl addr{};
+  addr.nl_family = AF_NETLINK;
+  addr.nl_groups = RTMGRP_LINK | RTMGRP_NOTIFY |
+                   RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_ROUTE |
+                   RTMGRP_IPV6_IFADDR | RTMGRP_IPV6_ROUTE;
+  if (::bind(fd, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) < 0) {
+    BOOST_THROW_EXCEPTION(Error(std::string("Cannot bind netlink socket (") +
+                                std::strerror(errno) + ")"));
+  }
+
+  // find out what pid has been assigned to us
+  socklen_t len = sizeof(addr);
+  if (::getsockname(fd, reinterpret_cast<sockaddr*>(&addr), &len) < 0) {
+    BOOST_THROW_EXCEPTION(Error(std::string("Cannot obtain netlink socket address (") +
+                                std::strerror(errno) + ")"));
+  }
+  if (len != sizeof(addr)) {
+    BOOST_THROW_EXCEPTION(Error("Wrong address length (" + to_string(len) + ")"));
+  }
+  if (addr.nl_family != AF_NETLINK) {
+    BOOST_THROW_EXCEPTION(Error("Wrong address family (" + to_string(addr.nl_family) + ")"));
+  }
+  m_pid = addr.nl_pid;
+  NDN_LOG_TRACE("our pid is " << m_pid);
+}
+
+void
+NetworkMonitor::Impl::sendDumpRequest(uint16_t nlmsgType)
+{
+  auto request = make_shared<RtnlRequest>();
+  request->nlh.nlmsg_len = sizeof(RtnlRequest);
+  request->nlh.nlmsg_type = nlmsgType;
+  request->nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
+  request->nlh.nlmsg_seq = ++m_sequenceNo;
+  request->nlh.nlmsg_pid = m_pid;
+  request->ifi.ifi_family = AF_UNSPEC;
+  request->rta.rta_type = IFLA_EXT_MASK;
+  request->rta.rta_len = RTA_LENGTH(sizeof(request->rtext));
+  request->rtext = 1 << 3; // RTEXT_FILTER_SKIP_STATS
+
+  boost::asio::async_write(*m_socket, boost::asio::buffer(request.get(), sizeof(RtnlRequest)),
+    // capture 'request' to prevent its premature deallocation
+    [request] (const boost::system::error_code& error, size_t) {
+      if (error && error != boost::asio::error::operation_aborted) {
+        NDN_LOG_ERROR("write failed: " << error.message());
+        BOOST_THROW_EXCEPTION(Error("Failed to send netlink request (" + error.message() + ")"));
+      }
+    });
+}
+
+static const char*
+nlmsgTypeToString(uint16_t type)
+{
+#define NDN_NLMSG_STRING(x) case NLMSG_##x: return "<" #x ">"
+#define NDN_RTM_STRING(x) case RTM_##x: return "<" #x ">"
+  switch (type) {
+    NDN_NLMSG_STRING(NOOP);
+    NDN_NLMSG_STRING(ERROR);
+    NDN_NLMSG_STRING(DONE);
+    NDN_NLMSG_STRING(OVERRUN);
+    NDN_RTM_STRING(NEWLINK);
+    NDN_RTM_STRING(DELLINK);
+    NDN_RTM_STRING(NEWADDR);
+    NDN_RTM_STRING(DELADDR);
+    NDN_RTM_STRING(NEWROUTE);
+    NDN_RTM_STRING(DELROUTE);
+    default:
+      return "";
+  }
+#undef NDN_NLMSG_STRING
+#undef NDN_RTM_STRING
+}
+
+static InterfaceType
+ifiTypeToInterfaceType(uint16_t type)
+{
+  switch (type) {
+    case ARPHRD_ETHER:
+      return InterfaceType::ETHERNET;
+    case ARPHRD_LOOPBACK:
+      return InterfaceType::LOOPBACK;
+    default:
+      return InterfaceType::UNKNOWN;
+  }
+}
+
+static AddressFamily
+ifaFamilyToAddressFamily(uint8_t family)
+{
+  switch (family) {
+    case AF_INET:
+      return AddressFamily::V4;
+    case AF_INET6:
+      return AddressFamily::V6;
+    default:
+      return AddressFamily::UNSPECIFIED;
+  }
+}
+
+static AddressScope
+ifaScopeToAddressScope(uint8_t scope)
+{
+  switch (scope) {
+    case RT_SCOPE_NOWHERE:
+      return AddressScope::NOWHERE;
+    case RT_SCOPE_HOST:
+      return AddressScope::HOST;
+    case RT_SCOPE_LINK:
+      return AddressScope::LINK;
+    default:
+      return AddressScope::GLOBAL;
+  }
+}
+
+void
+NetworkMonitor::Impl::asyncRead()
+{
+  m_socket->async_read_some(boost::asio::buffer(m_buffer),
+                            bind(&Impl::handleRead, this, _1, _2, m_socket));
+}
+
+void
+NetworkMonitor::Impl::handleRead(const boost::system::error_code& error, size_t nBytesRead,
+                                 const shared_ptr<boost::asio::posix::stream_descriptor>& socket)
+{
+  if (!socket->is_open() ||
+      error == boost::asio::error::operation_aborted) {
+    // socket was closed, ignore the error
+    NDN_LOG_TRACE("socket closed or operation aborted");
+    return;
+  }
+  if (error) {
+    NDN_LOG_ERROR("read failed: " << error.message());
+    BOOST_THROW_EXCEPTION(Error("Netlink socket read failed (" + error.message() + ")"));
+  }
+
+  NDN_LOG_TRACE("read " << nBytesRead << " bytes from netlink socket");
+
+  const nlmsghdr* nlh = reinterpret_cast<const nlmsghdr*>(m_buffer.data());
+  if (!isEnumerating() || (nlh->nlmsg_seq == m_sequenceNo && nlh->nlmsg_pid == m_pid)) {
+    parseNetlinkMessage(nlh, nBytesRead);
+  }
+  else {
+    NDN_LOG_TRACE("seq/pid mismatch, ignoring");
+  }
+
+  asyncRead();
+}
+
+void
+NetworkMonitor::Impl::parseNetlinkMessage(const nlmsghdr* nlh, size_t len)
+{
+  while (NLMSG_OK(nlh, len)) {
+    NDN_LOG_TRACE("parsing " << (nlh->nlmsg_flags & NLM_F_MULTI ? "multi-part " : "") <<
+                  "message type=" << nlh->nlmsg_type << nlmsgTypeToString(nlh->nlmsg_type) <<
+                  " len=" << nlh->nlmsg_len <<
+                  " seq=" << nlh->nlmsg_seq <<
+                  " pid=" << nlh->nlmsg_pid);
+
+    if (nlh->nlmsg_flags & NLM_F_DUMP_INTR) {
+      NDN_LOG_ERROR("netlink dump was interrupted");
+      // TODO: technically we should retry the dump...
+      break;
+    }
+
+    if (nlh->nlmsg_type == NLMSG_DONE)
+      break;
+
+    switch (nlh->nlmsg_type) {
+      case RTM_NEWLINK:
+      case RTM_DELLINK:
+        parseLinkMessage(nlh, reinterpret_cast<const ifinfomsg*>(NLMSG_DATA(nlh)));
+        if (!isEnumerating())
+          m_nm.onNetworkStateChanged(); // backward compat
+        break;
+
+      case RTM_NEWADDR:
+      case RTM_DELADDR:
+        parseAddressMessage(nlh, reinterpret_cast<const ifaddrmsg*>(NLMSG_DATA(nlh)));
+        if (!isEnumerating())
+          m_nm.onNetworkStateChanged(); // backward compat
+        break;
+
+      case RTM_NEWROUTE:
+      case RTM_DELROUTE:
+        parseRouteMessage(nlh, reinterpret_cast<const rtmsg*>(NLMSG_DATA(nlh)));
+        if (!isEnumerating())
+          m_nm.onNetworkStateChanged(); // backward compat
+        break;
+
+      case NLMSG_ERROR: {
+        const nlmsgerr* err = reinterpret_cast<const nlmsgerr*>(NLMSG_DATA(nlh));
+        if (nlh->nlmsg_len < NLMSG_LENGTH(sizeof(nlmsgerr)))
+          NDN_LOG_ERROR("truncated NLMSG_ERROR");
+        else if (err->error == 0)
+          // an error code of zero indicates an ACK message, not an error
+          NDN_LOG_TRACE("ACK");
+        else
+          NDN_LOG_ERROR("NLMSG_ERROR: " << std::strerror(std::abs(err->error)));
+        break;
+      }
+    }
+
+    nlh = NLMSG_NEXT(nlh, len);
+  }
+
+  if (nlh->nlmsg_type == NLMSG_DONE && m_isEnumeratingLinks) {
+    // links enumeration complete, now request all the addresses
+    m_isEnumeratingLinks = false;
+    NDN_LOG_TRACE("enumerating addresses");
+    sendDumpRequest(RTM_GETADDR);
+    m_isEnumeratingAddresses = true;
+  }
+  else if (nlh->nlmsg_type == NLMSG_DONE && m_isEnumeratingAddresses) {
+    // links and addresses enumeration complete
+    m_isEnumeratingAddresses = false;
+    // TODO: enumerate routes
+    NDN_LOG_DEBUG("enumeration complete");
+    m_nm.onEnumerationCompleted();
+  }
+}
+
+void
+NetworkMonitor::Impl::parseLinkMessage(const nlmsghdr* nlh, const ifinfomsg* ifi)
+{
+  if (ifiTypeToInterfaceType(ifi->ifi_type) == InterfaceType::UNKNOWN) {
+    NDN_LOG_DEBUG("unhandled interface type " << ifi->ifi_type);
+    return;
+  }
+
+  shared_ptr<NetworkInterface> interface;
+  auto it = m_interfaces.find(ifi->ifi_index);
+  if (it != m_interfaces.end()) {
+    interface = it->second;
+    BOOST_ASSERT(interface != nullptr);
+    BOOST_ASSERT(interface->getIndex() == ifi->ifi_index);
+  }
+
+  if (nlh->nlmsg_type == RTM_DELLINK) {
+    if (interface != nullptr) {
+      NDN_LOG_DEBUG("removing interface " << interface->getName());
+      m_interfaces.erase(it);
+      m_nm.onInterfaceRemoved(interface);
+    }
+    return;
+  }
+
+  if (interface == nullptr) {
+    // cannot use make_shared because NetworkInterface constructor is private
+    interface.reset(new NetworkInterface);
+    interface->setIndex(ifi->ifi_index);
+  }
+  interface->setType(ifiTypeToInterfaceType(ifi->ifi_type));
+  interface->setFlags(ifi->ifi_flags);
+
+  const rtattr* rta = reinterpret_cast<const rtattr*>(IFLA_RTA(ifi));
+  size_t rtaTotalLen = IFLA_PAYLOAD(nlh);
+  uint8_t operState = linux_if::OPER_STATE_UNKNOWN;
+
+  while (RTA_OK(rta, rtaTotalLen)) {
+    size_t attrLen = RTA_PAYLOAD(rta);
+
+    switch (rta->rta_type) {
+      case IFLA_ADDRESS:
+        if (attrLen == ethernet::ADDR_LEN) {
+          ethernet::Address addr(reinterpret_cast<const uint8_t*>(RTA_DATA(rta)));
+          interface->setEthernetAddress(addr);
+        }
+        break;
+
+      case IFLA_BROADCAST:
+        if (attrLen == ethernet::ADDR_LEN) {
+          ethernet::Address addr(reinterpret_cast<const uint8_t*>(RTA_DATA(rta)));
+          interface->setEthernetBroadcastAddress(addr);
+        }
+        break;
+
+      case IFLA_IFNAME: {
+        auto attrData = reinterpret_cast<const char*>(RTA_DATA(rta));
+        if (::strnlen(attrData, attrLen) <= attrLen)
+          interface->setName(attrData);
+        break;
+      }
+
+      case IFLA_MTU:
+        if (attrLen == sizeof(uint32_t))
+          interface->setMtu(*(reinterpret_cast<const uint32_t*>(RTA_DATA(rta))));
+        break;
+
+      case IFLA_OPERSTATE:
+        if (attrLen == sizeof(uint8_t))
+          operState = *(reinterpret_cast<const uint8_t*>RTA_DATA(rta));
+        break;
+    }
+
+    rta = RTA_NEXT(rta, rtaTotalLen);
+  }
+
+  updateInterfaceState(*interface, operState);
+
+  if (it == m_interfaces.end()) {
+    NDN_LOG_DEBUG("adding interface " << interface->getName());
+    m_interfaces[interface->getIndex()] = interface;
+    m_nm.onInterfaceAdded(interface);
+  }
+}
+
+void
+NetworkMonitor::Impl::parseAddressMessage(const nlmsghdr* nlh, const ifaddrmsg* ifa)
+{
+  auto it = m_interfaces.find(ifa->ifa_index);
+  if (it == m_interfaces.end()) {
+    // unknown interface, ignore message
+    NDN_LOG_TRACE("unknown interface index " << ifa->ifa_index);
+    return;
+  }
+  auto interface = it->second;
+  BOOST_ASSERT(interface != nullptr);
+
+  namespace ip = boost::asio::ip;
+
+  NetworkAddress address;
+  address.m_family = ifaFamilyToAddressFamily(ifa->ifa_family);
+  BOOST_ASSERT(address.m_family != AddressFamily::UNSPECIFIED);
+  address.m_prefixLength = ifa->ifa_prefixlen;
+  address.m_flags = ifa->ifa_flags; // will be overridden by IFA_FLAGS below, if the attribute is present
+  address.m_scope = ifaScopeToAddressScope(ifa->ifa_scope);
+
+  const rtattr* rta = reinterpret_cast<const rtattr*>(IFA_RTA(ifa));
+  size_t rtaTotalLen = IFA_PAYLOAD(nlh);
+
+  while (RTA_OK(rta, rtaTotalLen)) {
+    auto attrData = reinterpret_cast<const unsigned char*>(RTA_DATA(rta));
+    size_t attrLen = RTA_PAYLOAD(rta);
+
+    switch (rta->rta_type) {
+      case IFA_LOCAL:
+        if (ifa->ifa_family == AF_INET && attrLen == sizeof(ip::address_v4::bytes_type)) {
+          ip::address_v4::bytes_type bytes;
+          std::copy_n(attrData, bytes.size(), bytes.begin());
+          address.m_ip = ip::address_v4(bytes);
+        }
+        break;
+
+      case IFA_ADDRESS:
+        if (ifa->ifa_family == AF_INET6 && attrLen == sizeof(ip::address_v6::bytes_type)) {
+          ip::address_v6::bytes_type bytes;
+          std::copy_n(attrData, bytes.size(), bytes.begin());
+          address.m_ip = ip::address_v6(bytes);
+        }
+        break;
+
+      case IFA_BROADCAST:
+        if (ifa->ifa_family == AF_INET && attrLen == sizeof(ip::address_v4::bytes_type)) {
+          ip::address_v4::bytes_type bytes;
+          std::copy_n(attrData, bytes.size(), bytes.begin());
+          address.m_broadcast = ip::address_v4(bytes);
+        }
+        break;
+
+#ifdef NDN_CXX_HAVE_IFA_FLAGS
+      case IFA_FLAGS:
+        if (attrLen == sizeof(uint32_t))
+          address.m_flags = *(reinterpret_cast<const uint32_t*>(attrData));
+        break;
+#endif // NDN_CXX_HAVE_IFA_FLAGS
+    }
+
+    rta = RTA_NEXT(rta, rtaTotalLen);
+  }
+
+  if (nlh->nlmsg_type == RTM_NEWADDR)
+    interface->addNetworkAddress(address);
+  else if (nlh->nlmsg_type == RTM_DELADDR)
+    interface->removeNetworkAddress(address);
+}
+
+void
+NetworkMonitor::Impl::parseRouteMessage(const nlmsghdr* nlh, const rtmsg* rtm)
+{
+  // TODO
+}
+
+void
+NetworkMonitor::Impl::updateInterfaceState(NetworkInterface& interface, uint8_t operState)
+{
+  if (operState == linux_if::OPER_STATE_UP) {
+    interface.setState(InterfaceState::RUNNING);
+  }
+  else if (operState == linux_if::OPER_STATE_DORMANT) {
+    interface.setState(InterfaceState::DORMANT);
+  }
+  else {
+    // fallback to flags
+    auto flags = interface.getFlags();
+    if ((flags & linux_if::FLAG_LOWER_UP) && !(flags & linux_if::FLAG_DORMANT))
+      interface.setState(InterfaceState::RUNNING);
+    else if (flags & IFF_UP)
+      interface.setState(InterfaceState::NO_CARRIER);
+    else
+      interface.setState(InterfaceState::DOWN);
+  }
+}
+
+} // namespace net
+} // namespace ndn
diff --git a/src/net/detail/network-monitor-impl-rtnl.hpp b/src/net/detail/network-monitor-impl-rtnl.hpp
new file mode 100644
index 0000000..d43abce
--- /dev/null
+++ b/src/net/detail/network-monitor-impl-rtnl.hpp
@@ -0,0 +1,126 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2017 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Davide Pesavento <davide.pesavento@lip6.fr>
+ */
+
+#ifndef NDN_NET_NETWORK_MONITOR_IMPL_RTNL_HPP
+#define NDN_NET_NETWORK_MONITOR_IMPL_RTNL_HPP
+
+#include "ndn-cxx-config.hpp"
+#include "../network-monitor.hpp"
+
+#ifndef NDN_CXX_HAVE_RTNETLINK
+#error "This file should not be compiled ..."
+#endif
+
+#include <boost/asio/posix/stream_descriptor.hpp>
+
+#include <array>
+#include <map>
+
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/if_addr.h>
+#include <linux/if_link.h>
+
+namespace ndn {
+namespace net {
+
+class NetworkMonitor::Impl
+{
+public:
+  /** \brief initialize netlink socket and start enumerating interfaces
+   */
+  Impl(NetworkMonitor& nm, boost::asio::io_service& io);
+
+  ~Impl();
+
+  uint32_t
+  getCapabilities() const
+  {
+    return NetworkMonitor::CAP_ENUM |
+           NetworkMonitor::CAP_IF_ADD_REMOVE |
+           NetworkMonitor::CAP_STATE_CHANGE |
+           NetworkMonitor::CAP_MTU_CHANGE |
+           NetworkMonitor::CAP_ADDR_ADD_REMOVE;
+  }
+
+  shared_ptr<NetworkInterface>
+  getNetworkInterface(const std::string& ifname) const;
+
+  std::vector<shared_ptr<NetworkInterface>>
+  listNetworkInterfaces() const;
+
+private:
+  struct RtnlRequest
+  {
+    nlmsghdr nlh;
+    ifinfomsg ifi;
+    rtattr rta __attribute__((aligned(NLMSG_ALIGNTO))); // rtattr has to be aligned
+    uint32_t rtext;                                     // space for IFLA_EXT_MASK
+  };
+
+  bool
+  isEnumerating() const;
+
+  void
+  initSocket();
+
+  void
+  sendDumpRequest(uint16_t nlmsgType);
+
+  void
+  asyncRead();
+
+  void
+  handleRead(const boost::system::error_code& error, size_t nBytesReceived,
+             const shared_ptr<boost::asio::posix::stream_descriptor>& socket);
+
+  void
+  parseNetlinkMessage(const nlmsghdr* nlh, size_t len);
+
+  void
+  parseLinkMessage(const nlmsghdr* nlh, const ifinfomsg* ifi);
+
+  void
+  parseAddressMessage(const nlmsghdr* nlh, const ifaddrmsg* ifa);
+
+  void
+  parseRouteMessage(const nlmsghdr* nlh, const rtmsg* rtm);
+
+  static void
+  updateInterfaceState(NetworkInterface& interface, uint8_t operState);
+
+private:
+  NetworkMonitor& m_nm;
+  std::map<int /*ifindex*/, shared_ptr<NetworkInterface>> m_interfaces; ///< interface map
+  std::array<uint8_t, 16384> m_buffer; ///< holds netlink messages received from the kernel
+  shared_ptr<boost::asio::posix::stream_descriptor> m_socket; ///< the netlink socket
+  uint32_t m_pid; ///< our port ID (unicast address for netlink sockets)
+  uint32_t m_sequenceNo; ///< sequence number of the last netlink request sent to the kernel
+  bool m_isEnumeratingLinks; ///< true if a dump of all links is in progress
+  bool m_isEnumeratingAddresses; ///< true if a dump of all addresses is in progress
+};
+
+} // namespace net
+} // namespace ndn
+
+#endif // NDN_NET_NETWORK_MONITOR_IMPL_RTNL_HPP
diff --git a/src/net/dns.cpp b/src/net/dns.cpp
new file mode 100644
index 0000000..0043ec9
--- /dev/null
+++ b/src/net/dns.cpp
@@ -0,0 +1,160 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2017 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#include "dns.hpp"
+#include "../util/scheduler.hpp"
+
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/ip/udp.hpp>
+
+namespace ndn {
+namespace dns {
+
+class Resolver : noncopyable
+{
+public:
+  typedef boost::asio::ip::udp protocol;
+  typedef protocol::resolver::iterator iterator;
+  typedef protocol::resolver::query query;
+
+public:
+  Resolver(boost::asio::io_service& ioService,
+           const AddressSelector& addressSelector)
+    : m_resolver(ioService)
+    , m_addressSelector(addressSelector)
+    , m_scheduler(ioService)
+  {
+    BOOST_ASSERT(m_addressSelector != nullptr);
+  }
+
+  void
+  asyncResolve(const query& q,
+               const SuccessCallback& onSuccess,
+               const ErrorCallback& onError,
+               time::nanoseconds timeout,
+               const shared_ptr<Resolver>& self)
+  {
+    m_onSuccess = onSuccess;
+    m_onError = onError;
+
+    m_resolver.async_resolve(q, bind(&Resolver::onResolveResult, this, _1, _2, self));
+
+    m_resolveTimeout = m_scheduler.scheduleEvent(timeout, bind(&Resolver::onResolveTimeout, this, self));
+  }
+
+  iterator
+  syncResolve(const query& q)
+  {
+    return selectAddress(m_resolver.resolve(q));
+  }
+
+private:
+  void
+  onResolveResult(const boost::system::error_code& error,
+                  iterator it, const shared_ptr<Resolver>& self)
+  {
+    m_scheduler.cancelEvent(m_resolveTimeout);
+    // ensure the Resolver isn't destructed while callbacks are still pending, see #2653
+    m_resolver.get_io_service().post(bind([] (const shared_ptr<Resolver>&) {}, self));
+
+    if (error) {
+      if (error == boost::asio::error::operation_aborted)
+        return;
+
+      if (m_onError)
+        m_onError("Hostname cannot be resolved: " + error.message());
+
+      return;
+    }
+
+    it = selectAddress(it);
+
+    if (it != iterator() && m_onSuccess) {
+      m_onSuccess(it->endpoint().address());
+    }
+    else if (m_onError) {
+      m_onError("No endpoints match the specified address selector");
+    }
+  }
+
+  void
+  onResolveTimeout(const shared_ptr<Resolver>& self)
+  {
+    m_resolver.cancel();
+    // ensure the Resolver isn't destructed while callbacks are still pending, see #2653
+    m_resolver.get_io_service().post(bind([] (const shared_ptr<Resolver>&) {}, self));
+
+    if (m_onError)
+      m_onError("Hostname resolution timed out");
+  }
+
+  iterator
+  selectAddress(iterator it) const
+  {
+    while (it != iterator() &&
+           !m_addressSelector(it->endpoint().address())) {
+      ++it;
+    }
+
+    return it;
+  }
+
+private:
+  protocol::resolver m_resolver;
+
+  AddressSelector m_addressSelector;
+  SuccessCallback m_onSuccess;
+  ErrorCallback m_onError;
+
+  util::scheduler::Scheduler m_scheduler;
+  util::scheduler::EventId m_resolveTimeout;
+};
+
+void
+asyncResolve(const std::string& host,
+             const SuccessCallback& onSuccess,
+             const ErrorCallback& onError,
+             boost::asio::io_service& ioService,
+             const AddressSelector& addressSelector,
+             time::nanoseconds timeout)
+{
+  auto resolver = make_shared<Resolver>(ref(ioService), addressSelector);
+  resolver->asyncResolve(Resolver::query(host, ""), onSuccess, onError, timeout, resolver);
+  // resolver will be destroyed when async operation finishes or ioService stops
+}
+
+IpAddress
+syncResolve(const std::string& host,
+            boost::asio::io_service& ioService,
+            const AddressSelector& addressSelector)
+{
+  Resolver resolver(ioService, addressSelector);
+  auto it = resolver.syncResolve(Resolver::query(host, ""));
+
+  if (it == Resolver::iterator()) {
+    BOOST_THROW_EXCEPTION(Error("No endpoints match the specified address selector"));
+  }
+
+  return it->endpoint().address();
+}
+
+} // namespace dns
+} // namespace ndn
diff --git a/src/net/dns.hpp b/src/net/dns.hpp
new file mode 100644
index 0000000..79d9a10
--- /dev/null
+++ b/src/net/dns.hpp
@@ -0,0 +1,124 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2017 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#ifndef NDN_NET_DNS_HPP
+#define NDN_NET_DNS_HPP
+
+#include "../util/time.hpp"
+
+#include <boost/asio/ip/address.hpp>
+
+// forward declaration
+namespace boost {
+namespace asio {
+class io_service;
+} // namespace asio
+} // namespace boost
+
+namespace ndn {
+namespace dns {
+
+typedef boost::asio::ip::address IpAddress;
+typedef function<bool (const IpAddress& address)> AddressSelector;
+
+struct AnyAddress
+{
+  bool
+  operator()(const IpAddress& address) const
+  {
+    return true;
+  }
+};
+
+struct Ipv4Only
+{
+  bool
+  operator()(const IpAddress& address) const
+  {
+    return address.is_v4();
+  }
+};
+
+struct Ipv6Only
+{
+  bool
+  operator()(const IpAddress& address) const
+  {
+    return address.is_v6();
+  }
+};
+
+struct Error : public std::runtime_error
+{
+  explicit
+  Error(const std::string& what)
+    : std::runtime_error(what)
+  {
+  }
+};
+
+typedef function<void (const IpAddress& address)> SuccessCallback;
+typedef function<void (const std::string& reason)> ErrorCallback;
+
+/** \brief Asynchronously resolve host
+ *
+ * If an address selector predicate is specified, then each resolved IP address
+ * is checked against the predicate.
+ *
+ * Available address selector predicates:
+ *
+ * - dns::AnyAddress()
+ * - dns::Ipv4Address()
+ * - dns::Ipv6Address()
+ *
+ * \warning Even after the DNS resolution has timed out, it's possible that
+ *          \p ioService keeps running and \p onSuccess is invoked at a later time.
+ *          This could cause segmentation fault if \p onSuccess is deallocated.
+ *          To stop the io_service, explicitly invoke \p ioService.stop().
+ */
+void
+asyncResolve(const std::string& host,
+             const SuccessCallback& onSuccess,
+             const ErrorCallback& onError,
+             boost::asio::io_service& ioService,
+             const AddressSelector& addressSelector = AnyAddress(),
+             time::nanoseconds timeout = time::seconds(4));
+
+/** \brief Synchronously resolve host
+ *
+ * If an address selector predicate is specified, then each resolved IP address
+ * is checked against the predicate.
+ *
+ * Available address selector predicates:
+ *
+ * - dns::AnyAddress()
+ * - dns::Ipv4Address()
+ * - dns::Ipv6Address()
+ */
+IpAddress
+syncResolve(const std::string& host,
+            boost::asio::io_service& ioService,
+            const AddressSelector& addressSelector = AnyAddress());
+
+} // namespace dns
+} // namespace ndn
+
+#endif // NDN_NET_DNS_HPP
diff --git a/src/net/ethernet.cpp b/src/net/ethernet.cpp
new file mode 100644
index 0000000..0efdd58
--- /dev/null
+++ b/src/net/ethernet.cpp
@@ -0,0 +1,147 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2017 Regents of the University of California,
+ *                         Arizona Board of Regents,
+ *                         Colorado State University,
+ *                         University Pierre & Marie Curie, Sorbonne University,
+ *                         Washington University in St. Louis,
+ *                         Beijing Institute of Technology,
+ *                         The University of Memphis.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#include "ethernet.hpp"
+
+#include <boost/functional/hash.hpp>
+
+#include <stdio.h>
+#include <ostream>
+
+namespace ndn {
+namespace ethernet {
+
+Address::Address()
+{
+  fill(0);
+}
+
+Address::Address(uint8_t a1, uint8_t a2, uint8_t a3, uint8_t a4, uint8_t a5, uint8_t a6)
+{
+  data()[0] = a1;
+  data()[1] = a2;
+  data()[2] = a3;
+  data()[3] = a4;
+  data()[4] = a5;
+  data()[5] = a6;
+}
+
+Address::Address(const uint8_t octets[ADDR_LEN])
+{
+  std::copy(octets, octets + size(), begin());
+}
+
+bool
+Address::isBroadcast() const
+{
+  return *this == getBroadcastAddress();
+}
+
+bool
+Address::isMulticast() const
+{
+  return (at(0) & 1) != 0;
+}
+
+bool
+Address::isNull() const
+{
+  return *this == Address();
+}
+
+std::string
+Address::toString(char sep) const
+{
+  char s[18]; // 12 digits + 5 separators + null terminator
+
+  // - apparently gcc-4.6 does not support the 'hh' type modifier
+  // - std::snprintf not found in some environments
+  //   https://redmine.named-data.net/issues/2299 for more information
+  snprintf(s, sizeof(s), "%02x%c%02x%c%02x%c%02x%c%02x%c%02x",
+           at(0), sep, at(1), sep, at(2), sep, at(3), sep, at(4), sep, at(5));
+
+  return std::string(s);
+}
+
+Address
+Address::fromString(const std::string& str)
+{
+  Address a;
+  unsigned short temp[a.size()];
+  char sep[5][2]; // 5 * (1 separator char + 1 null terminator)
+  int n = 0; // num of chars read from the input string
+
+  // apparently gcc-4.6 does not support the 'hh' type modifier
+  int ret = std::sscanf(str.c_str(), "%2hx%1[:-]%2hx%1[:-]%2hx%1[:-]%2hx%1[:-]%2hx%1[:-]%2hx%n",
+                        &temp[0], &sep[0][0], &temp[1], &sep[1][0], &temp[2], &sep[2][0],
+                        &temp[3], &sep[3][0], &temp[4], &sep[4][0], &temp[5], &n);
+
+  if (ret < 11 || static_cast<size_t>(n) != str.length())
+    return Address();
+
+  for (size_t i = 0; i < a.size(); ++i)
+    {
+      // check that all separators are actually the same char (: or -)
+      if (i < 5 && sep[i][0] != sep[0][0])
+        return Address();
+
+      // check that each value fits into a uint8_t
+      if (temp[i] > 0xFF)
+        return Address();
+
+      a[i] = static_cast<uint8_t>(temp[i]);
+    }
+
+  return a;
+}
+
+Address
+getBroadcastAddress()
+{
+  return { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+}
+
+Address
+getDefaultMulticastAddress()
+{
+  return { 0x01, 0x00, 0x5E, 0x00, 0x17, 0xAA };
+}
+
+std::ostream&
+operator<<(std::ostream& o, const Address& a)
+{
+  return o << a.toString();
+}
+
+} // namespace ethernet
+} // namespace ndn
+
+std::size_t
+std::hash<ndn::ethernet::Address>::operator()(const ndn::ethernet::Address& a) const noexcept
+{
+  return boost::hash_range(a.cbegin(), a.cend());
+}
diff --git a/src/net/ethernet.hpp b/src/net/ethernet.hpp
new file mode 100644
index 0000000..d4b8f47
--- /dev/null
+++ b/src/net/ethernet.hpp
@@ -0,0 +1,125 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2017 Regents of the University of California,
+ *                         Arizona Board of Regents,
+ *                         Colorado State University,
+ *                         University Pierre & Marie Curie, Sorbonne University,
+ *                         Washington University in St. Louis,
+ *                         Beijing Institute of Technology,
+ *                         The University of Memphis.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#ifndef NDN_NET_ETHERNET_HPP
+#define NDN_NET_ETHERNET_HPP
+
+#include <array>
+#include <cstdint>
+#include <functional>
+#include <string>
+
+namespace ndn {
+namespace ethernet {
+
+const uint16_t ETHERTYPE_NDN = 0x8624;
+
+const size_t ADDR_LEN     = 6;      ///< Octets in one Ethernet address
+const size_t TYPE_LEN     = 2;      ///< Octets in Ethertype field
+const size_t HDR_LEN      = 14;     ///< Total octets in Ethernet header (without 802.1Q tag)
+const size_t TAG_LEN      = 4;      ///< Octets in 802.1Q tag (TPID + priority + VLAN)
+const size_t MIN_DATA_LEN = 46;     ///< Min octets in Ethernet payload (assuming no 802.1Q tag)
+const size_t MAX_DATA_LEN = 1500;   ///< Max octets in Ethernet payload
+const size_t CRC_LEN      = 4;      ///< Octets in Ethernet frame check sequence
+
+
+/** \brief represents an Ethernet hardware address
+ */
+class Address : public std::array<uint8_t, ADDR_LEN>
+{
+public:
+  /// Constructs a null Ethernet address (00:00:00:00:00:00)
+  Address();
+
+  /// Constructs a new Ethernet address with the given octets
+  Address(uint8_t a1, uint8_t a2, uint8_t a3,
+          uint8_t a4, uint8_t a5, uint8_t a6);
+
+  /// Constructs a new Ethernet address with the given octets
+  explicit
+  Address(const uint8_t octets[ADDR_LEN]);
+
+  /// True if this is a broadcast address (ff:ff:ff:ff:ff:ff)
+  bool
+  isBroadcast() const;
+
+  /// True if this is a multicast address
+  bool
+  isMulticast() const;
+
+  /// True if this is a null address (00:00:00:00:00:00)
+  bool
+  isNull() const;
+
+  /**
+   * \brief Converts the address to a human-readable string
+   *
+   * \param sep A character used to visually separate the octets,
+   *            usually ':' (the default value) or '-'
+   */
+  std::string
+  toString(char sep = ':') const;
+
+  /**
+   * \brief Creates an Address from a string containing an Ethernet address
+   *        in hexadecimal notation, with colons or hyphens as separators
+   *
+   * \param str The string to be parsed
+   * \return Always an instance of Address, which will be null
+   *         if the parsing fails
+   */
+  static Address
+  fromString(const std::string& str);
+};
+
+/// Returns the Ethernet broadcast address (ff:ff:ff:ff:ff:ff)
+Address
+getBroadcastAddress();
+
+/// Returns the default Ethernet multicast address for NDN
+Address
+getDefaultMulticastAddress();
+
+std::ostream&
+operator<<(std::ostream& o, const Address& a);
+
+} // namespace ethernet
+} // namespace ndn
+
+namespace std {
+
+// specialize std::hash<> for ethernet::Address
+template<>
+struct hash<ndn::ethernet::Address>
+{
+  size_t
+  operator()(const ndn::ethernet::Address& a) const noexcept;
+};
+
+} // namespace std
+
+#endif // NDN_NET_ETHERNET_HPP
diff --git a/src/net/face-uri.cpp b/src/net/face-uri.cpp
new file mode 100644
index 0000000..d550fd5
--- /dev/null
+++ b/src/net/face-uri.cpp
@@ -0,0 +1,622 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2017 Regents of the University of California,
+ *                         Arizona Board of Regents,
+ *                         Colorado State University,
+ *                         University Pierre & Marie Curie, Sorbonne University,
+ *                         Washington University in St. Louis,
+ *                         Beijing Institute of Technology,
+ *                         The University of Memphis.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#include "face-uri.hpp"
+#include "dns.hpp"
+
+#include <boost/lexical_cast.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/for_each.hpp>
+#include <boost/regex.hpp>
+#include <set>
+
+namespace ndn {
+
+BOOST_CONCEPT_ASSERT((boost::EqualityComparable<FaceUri>));
+
+FaceUri::FaceUri()
+  : m_isV6(false)
+{
+}
+
+FaceUri::FaceUri(const std::string& uri)
+{
+  if (!parse(uri)) {
+    BOOST_THROW_EXCEPTION(Error("Malformed URI: " + uri));
+  }
+}
+
+FaceUri::FaceUri(const char* uri)
+  : FaceUri(std::string(uri))
+{
+}
+
+bool
+FaceUri::parse(const std::string& uri)
+{
+  m_scheme.clear();
+  m_host.clear();
+  m_port.clear();
+  m_path.clear();
+  m_isV6 = false;
+
+  static const boost::regex protocolExp("(\\w+\\d?(\\+\\w+)?)://([^/]*)(\\/[^?]*)?");
+  boost::smatch protocolMatch;
+  if (!boost::regex_match(uri, protocolMatch, protocolExp)) {
+    return false;
+  }
+  m_scheme = protocolMatch[1];
+  const std::string& authority = protocolMatch[3];
+  m_path = protocolMatch[4];
+
+  // pattern for IPv6 address enclosed in [ ], with optional port number
+  static const boost::regex v6Exp("^\\[([a-fA-F0-9:]+)\\](?:\\:(\\d+))?$");
+  // pattern for Ethernet address in standard hex-digits-and-colons notation
+  static const boost::regex etherExp("^\\[((?:[a-fA-F0-9]{1,2}\\:){5}(?:[a-fA-F0-9]{1,2}))\\]$");
+  // pattern for IPv4-mapped IPv6 address, with optional port number
+  static const boost::regex v4MappedV6Exp("^\\[::ffff:(\\d+(?:\\.\\d+){3})\\](?:\\:(\\d+))?$");
+  // pattern for IPv4/hostname/fd/ifname, with optional port number
+  static const boost::regex v4HostExp("^([^:]+)(?:\\:(\\d+))?$");
+
+  if (authority.empty()) {
+    // UNIX, internal
+  }
+  else {
+    boost::smatch match;
+    m_isV6 = boost::regex_match(authority, match, v6Exp);
+    if (m_isV6 ||
+        boost::regex_match(authority, match, etherExp) ||
+        boost::regex_match(authority, match, v4MappedV6Exp) ||
+        boost::regex_match(authority, match, v4HostExp)) {
+      m_host = match[1];
+      m_port = match[2];
+    }
+    else {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+FaceUri::FaceUri(const boost::asio::ip::udp::endpoint& endpoint)
+{
+  m_isV6 = endpoint.address().is_v6();
+  m_scheme = m_isV6 ? "udp6" : "udp4";
+  m_host = endpoint.address().to_string();
+  m_port = to_string(endpoint.port());
+}
+
+FaceUri::FaceUri(const boost::asio::ip::tcp::endpoint& endpoint)
+{
+  m_isV6 = endpoint.address().is_v6();
+  m_scheme = m_isV6 ? "tcp6" : "tcp4";
+  m_host = endpoint.address().to_string();
+  m_port = to_string(endpoint.port());
+}
+
+FaceUri::FaceUri(const boost::asio::ip::tcp::endpoint& endpoint, const std::string& scheme)
+{
+  m_isV6 = endpoint.address().is_v6();
+  m_scheme = scheme;
+  m_host = endpoint.address().to_string();
+  m_port = to_string(endpoint.port());
+}
+
+#ifdef BOOST_ASIO_HAS_LOCAL_SOCKETS
+FaceUri::FaceUri(const boost::asio::local::stream_protocol::endpoint& endpoint)
+  : m_scheme("unix")
+  , m_path(endpoint.path())
+  , m_isV6(false)
+{
+}
+#endif // BOOST_ASIO_HAS_LOCAL_SOCKETS
+
+FaceUri
+FaceUri::fromFd(int fd)
+{
+  FaceUri uri;
+  uri.m_scheme = "fd";
+  uri.m_host = to_string(fd);
+  return uri;
+}
+
+FaceUri::FaceUri(const ethernet::Address& address)
+  : m_scheme("ether")
+  , m_host(address.toString())
+  , m_isV6(true)
+{
+}
+
+FaceUri
+FaceUri::fromDev(const std::string& ifname)
+{
+  FaceUri uri;
+  uri.m_scheme = "dev";
+  uri.m_host = ifname;
+  return uri;
+}
+
+FaceUri
+FaceUri::fromUdpDev(const boost::asio::ip::udp::endpoint& endpoint, const std::string& ifname)
+{
+  FaceUri uri;
+  uri.m_scheme = endpoint.address().is_v6() ? "udp6+dev" : "udp4+dev";
+  uri.m_host = ifname;
+  uri.m_port = to_string(endpoint.port());
+  return uri;
+}
+
+bool
+FaceUri::operator==(const FaceUri& rhs) const
+{
+  return m_isV6 == rhs.m_isV6 &&
+         m_scheme == rhs.m_scheme &&
+         m_host == rhs.m_host &&
+         m_port == rhs.m_port &&
+         m_path == rhs.m_path;
+}
+
+bool
+FaceUri::operator!=(const FaceUri& rhs) const
+{
+  return !(*this == rhs);
+}
+
+std::string
+FaceUri::toString() const
+{
+  std::ostringstream os;
+  os << *this;
+  return os.str();
+}
+
+std::ostream&
+operator<<(std::ostream& os, const FaceUri& uri)
+{
+  os << uri.m_scheme << "://";
+  if (uri.m_isV6) {
+    os << "[" << uri.m_host << "]";
+  }
+  else {
+    os << uri.m_host;
+  }
+  if (!uri.m_port.empty()) {
+    os << ":" << uri.m_port;
+  }
+  os << uri.m_path;
+  return os;
+}
+
+
+/** \brief a CanonizeProvider provides FaceUri canonization functionality for a group of schemes
+ */
+class CanonizeProvider : noncopyable
+{
+public:
+  virtual
+  ~CanonizeProvider() = default;
+
+  virtual std::set<std::string>
+  getSchemes() const = 0;
+
+  virtual bool
+  isCanonical(const FaceUri& faceUri) const = 0;
+
+  virtual void
+  canonize(const FaceUri& faceUri,
+           const FaceUri::CanonizeSuccessCallback& onSuccess,
+           const FaceUri::CanonizeFailureCallback& onFailure,
+           boost::asio::io_service& io, time::nanoseconds timeout) const = 0;
+};
+
+template<typename Protocol>
+class IpHostCanonizeProvider : public CanonizeProvider
+{
+public:
+  std::set<std::string>
+  getSchemes() const override
+  {
+    return {m_baseScheme, m_v4Scheme, m_v6Scheme};
+  }
+
+  bool
+  isCanonical(const FaceUri& faceUri) const override
+  {
+    if (faceUri.getPort().empty()) {
+      return false;
+    }
+    if (!faceUri.getPath().empty()) {
+      return false;
+    }
+
+    boost::system::error_code ec;
+    boost::asio::ip::address addr;
+    if (faceUri.getScheme() == m_v4Scheme) {
+      addr = boost::asio::ip::address_v4::from_string(faceUri.getHost(), ec);
+    }
+    else if (faceUri.getScheme() == m_v6Scheme) {
+      addr = boost::asio::ip::address_v6::from_string(faceUri.getHost(), ec);
+    }
+    else {
+      return false;
+    }
+
+    return !ec && addr.to_string() == faceUri.getHost() && checkAddress(addr).first;
+  }
+
+  void
+  canonize(const FaceUri& faceUri,
+           const FaceUri::CanonizeSuccessCallback& onSuccess,
+           const FaceUri::CanonizeFailureCallback& onFailure,
+           boost::asio::io_service& io, time::nanoseconds timeout) const override
+  {
+    if (this->isCanonical(faceUri)) {
+      onSuccess(faceUri);
+      return;
+    }
+
+    // make a copy because caller may modify faceUri
+    auto uri = make_shared<FaceUri>(faceUri);
+    boost::system::error_code ec;
+    auto ipAddress = boost::asio::ip::address::from_string(faceUri.getHost(), ec);
+    if (!ec) {
+      // No need to resolve IP address if host is already an IP
+      if ((faceUri.getScheme() == m_v4Scheme && !ipAddress.is_v4()) ||
+          (faceUri.getScheme() == m_v6Scheme && !ipAddress.is_v6())) {
+        return onFailure("IPv4/v6 mismatch");
+      }
+
+      onDnsSuccess(uri, onSuccess, onFailure, ipAddress);
+    }
+    else {
+      dns::AddressSelector addressSelector;
+      if (faceUri.getScheme() == m_v4Scheme) {
+        addressSelector = dns::Ipv4Only();
+      }
+      else if (faceUri.getScheme() == m_v6Scheme) {
+        addressSelector = dns::Ipv6Only();
+      }
+      else {
+        BOOST_ASSERT(faceUri.getScheme() == m_baseScheme);
+        addressSelector = dns::AnyAddress();
+      }
+
+      dns::asyncResolve(faceUri.getHost(),
+        bind(&IpHostCanonizeProvider<Protocol>::onDnsSuccess, this, uri, onSuccess, onFailure, _1),
+        bind(&IpHostCanonizeProvider<Protocol>::onDnsFailure, this, uri, onFailure, _1),
+        io, addressSelector, timeout);
+    }
+  }
+
+protected:
+  explicit
+  IpHostCanonizeProvider(const std::string& baseScheme,
+                         uint16_t defaultUnicastPort = 6363,
+                         uint16_t defaultMulticastPort = 56363)
+    : m_baseScheme(baseScheme)
+    , m_v4Scheme(baseScheme + '4')
+    , m_v6Scheme(baseScheme + '6')
+    , m_defaultUnicastPort(defaultUnicastPort)
+    , m_defaultMulticastPort(defaultMulticastPort)
+  {
+  }
+
+private:
+  void
+  onDnsSuccess(const shared_ptr<FaceUri>& faceUri,
+               const FaceUri::CanonizeSuccessCallback& onSuccess,
+               const FaceUri::CanonizeFailureCallback& onFailure,
+               const dns::IpAddress& ipAddress) const
+  {
+    bool isOk = false;
+    std::string reason;
+    std::tie(isOk, reason) = this->checkAddress(ipAddress);
+    if (!isOk) {
+      return onFailure(reason);
+    }
+
+    uint16_t port = 0;
+    if (faceUri->getPort().empty()) {
+      port = ipAddress.is_multicast() ? m_defaultMulticastPort : m_defaultUnicastPort;
+    }
+    else {
+      try {
+        port = boost::lexical_cast<uint16_t>(faceUri->getPort());
+      }
+      catch (const boost::bad_lexical_cast&) {
+        return onFailure("invalid port number '" + faceUri->getPort() + "'");
+      }
+    }
+
+    FaceUri canonicalUri(typename Protocol::endpoint(ipAddress, port));
+    BOOST_ASSERT(canonicalUri.isCanonical());
+    onSuccess(canonicalUri);
+  }
+
+  void
+  onDnsFailure(const shared_ptr<FaceUri>& faceUri,
+               const FaceUri::CanonizeFailureCallback& onFailure,
+               const std::string& reason) const
+  {
+    onFailure(reason);
+  }
+
+  /** \brief when overriden in a subclass, check the IP address is allowable
+   *  \return (true,ignored) if the address is allowable;
+   *          (false,reason) if the address is not allowable.
+   */
+  virtual std::pair<bool, std::string>
+  checkAddress(const dns::IpAddress& ipAddress) const
+  {
+    return {true, ""};
+  }
+
+private:
+  std::string m_baseScheme;
+  std::string m_v4Scheme;
+  std::string m_v6Scheme;
+  uint16_t m_defaultUnicastPort;
+  uint16_t m_defaultMulticastPort;
+};
+
+class UdpCanonizeProvider : public IpHostCanonizeProvider<boost::asio::ip::udp>
+{
+public:
+  UdpCanonizeProvider()
+    : IpHostCanonizeProvider("udp")
+  {
+  }
+
+protected:
+  // checkAddress is not overriden:
+  // Although NFD doesn't support IPv6 multicast, it's an implementation limitation.
+  // FaceMgmt protocol allows IPv6 multicast address in UDP.
+};
+
+class TcpCanonizeProvider : public IpHostCanonizeProvider<boost::asio::ip::tcp>
+{
+public:
+  TcpCanonizeProvider()
+    : IpHostCanonizeProvider("tcp")
+  {
+  }
+
+protected:
+  std::pair<bool, std::string>
+  checkAddress(const dns::IpAddress& ipAddress) const override
+  {
+    if (ipAddress.is_multicast()) {
+      return {false, "cannot use multicast address"};
+    }
+    return {true, ""};
+  }
+};
+
+class EtherCanonizeProvider : public CanonizeProvider
+{
+public:
+  std::set<std::string>
+  getSchemes() const override
+  {
+    return {"ether"};
+  }
+
+  bool
+  isCanonical(const FaceUri& faceUri) const override
+  {
+    if (!faceUri.getPort().empty()) {
+      return false;
+    }
+    if (!faceUri.getPath().empty()) {
+      return false;
+    }
+
+    auto addr = ethernet::Address::fromString(faceUri.getHost());
+    return addr.toString() == faceUri.getHost();
+  }
+
+  void
+  canonize(const FaceUri& faceUri,
+           const FaceUri::CanonizeSuccessCallback& onSuccess,
+           const FaceUri::CanonizeFailureCallback& onFailure,
+           boost::asio::io_service& io, time::nanoseconds timeout) const override
+  {
+    auto addr = ethernet::Address::fromString(faceUri.getHost());
+    if (addr.isNull()) {
+      return onFailure("invalid ethernet address '" + faceUri.getHost() + "'");
+    }
+
+    FaceUri canonicalUri(addr);
+    BOOST_ASSERT(canonicalUri.isCanonical());
+    onSuccess(canonicalUri);
+  }
+};
+
+class DevCanonizeProvider : public CanonizeProvider
+{
+public:
+  std::set<std::string>
+  getSchemes() const override
+  {
+    return {"dev"};
+  }
+
+  bool
+  isCanonical(const FaceUri& faceUri) const override
+  {
+    return !faceUri.getHost().empty() && faceUri.getPort().empty() && faceUri.getPath().empty();
+  }
+
+  void
+  canonize(const FaceUri& faceUri,
+           const FaceUri::CanonizeSuccessCallback& onSuccess,
+           const FaceUri::CanonizeFailureCallback& onFailure,
+           boost::asio::io_service& io, time::nanoseconds timeout) const override
+  {
+    if (faceUri.getHost().empty()) {
+      onFailure("network interface name is missing");
+      return;
+    }
+    if (!faceUri.getPort().empty()) {
+      onFailure("port number is not allowed");
+      return;
+    }
+    if (!faceUri.getPath().empty() && faceUri.getPath() != "/") { // permit trailing slash only
+      onFailure("path is not allowed");
+      return;
+    }
+
+    FaceUri canonicalUri = FaceUri::fromDev(faceUri.getHost());
+    BOOST_ASSERT(canonicalUri.isCanonical());
+    onSuccess(canonicalUri);
+  }
+};
+
+class UdpDevCanonizeProvider : public CanonizeProvider
+{
+public:
+  std::set<std::string>
+  getSchemes() const override
+  {
+    return {"udp4+dev", "udp6+dev"};
+  }
+
+  bool
+  isCanonical(const FaceUri& faceUri) const override
+  {
+    if (faceUri.getPort().empty()) {
+      return false;
+    }
+    if (!faceUri.getPath().empty()) {
+      return false;
+    }
+    return true;
+  }
+
+  void
+  canonize(const FaceUri& faceUri,
+           const FaceUri::CanonizeSuccessCallback& onSuccess,
+           const FaceUri::CanonizeFailureCallback& onFailure,
+           boost::asio::io_service& io, time::nanoseconds timeout) const override
+  {
+    if (this->isCanonical(faceUri)) {
+      onSuccess(faceUri);
+    }
+    else {
+      onFailure("cannot canonize " + faceUri.toString());
+    }
+  }
+};
+
+using CanonizeProviders = boost::mpl::vector<UdpCanonizeProvider*,
+                                             TcpCanonizeProvider*,
+                                             EtherCanonizeProvider*,
+                                             DevCanonizeProvider*,
+                                             UdpDevCanonizeProvider*>;
+using CanonizeProviderTable = std::map<std::string, shared_ptr<CanonizeProvider>>;
+
+class CanonizeProviderTableInitializer
+{
+public:
+  explicit
+  CanonizeProviderTableInitializer(CanonizeProviderTable& providerTable)
+    : m_providerTable(providerTable)
+  {
+  }
+
+  template<typename CP>
+  void
+  operator()(CP*)
+  {
+    shared_ptr<CanonizeProvider> cp = make_shared<CP>();
+    auto schemes = cp->getSchemes();
+    BOOST_ASSERT(!schemes.empty());
+
+    for (const auto& scheme : schemes) {
+      BOOST_ASSERT(m_providerTable.count(scheme) == 0);
+      m_providerTable[scheme] = cp;
+    }
+  }
+
+private:
+  CanonizeProviderTable& m_providerTable;
+};
+
+static const CanonizeProvider*
+getCanonizeProvider(const std::string& scheme)
+{
+  static CanonizeProviderTable providerTable;
+  if (providerTable.empty()) {
+    boost::mpl::for_each<CanonizeProviders>(CanonizeProviderTableInitializer(providerTable));
+    BOOST_ASSERT(!providerTable.empty());
+  }
+
+  auto it = providerTable.find(scheme);
+  return it == providerTable.end() ? nullptr : it->second.get();
+}
+
+
+bool
+FaceUri::canCanonize(const std::string& scheme)
+{
+  return getCanonizeProvider(scheme) != nullptr;
+}
+
+bool
+FaceUri::isCanonical() const
+{
+  const CanonizeProvider* cp = getCanonizeProvider(this->getScheme());
+  if (cp == nullptr) {
+    return false;
+  }
+
+  return cp->isCanonical(*this);
+}
+
+void
+FaceUri::canonize(const CanonizeSuccessCallback& onSuccess,
+                  const CanonizeFailureCallback& onFailure,
+                  boost::asio::io_service& io, time::nanoseconds timeout) const
+{
+  const CanonizeProvider* cp = getCanonizeProvider(this->getScheme());
+  if (cp == nullptr) {
+    if (onFailure) {
+      onFailure("scheme not supported");
+    }
+    return;
+  }
+
+  static CanonizeSuccessCallback successNop = bind([]{});
+  static CanonizeFailureCallback failureNop = bind([]{});
+  cp->canonize(*this,
+               onSuccess ? onSuccess : successNop,
+               onFailure ? onFailure : failureNop,
+               io, timeout);
+}
+
+} // namespace ndn
diff --git a/src/net/face-uri.hpp b/src/net/face-uri.hpp
new file mode 100644
index 0000000..12276cd
--- /dev/null
+++ b/src/net/face-uri.hpp
@@ -0,0 +1,197 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2017 Regents of the University of California,
+ *                         Arizona Board of Regents,
+ *                         Colorado State University,
+ *                         University Pierre & Marie Curie, Sorbonne University,
+ *                         Washington University in St. Louis,
+ *                         Beijing Institute of Technology,
+ *                         The University of Memphis.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#ifndef NDN_NET_FACE_URI_HPP
+#define NDN_NET_FACE_URI_HPP
+
+#include "ethernet.hpp"
+#include "../util/time.hpp"
+
+#include <boost/asio/ip/tcp.hpp>
+#include <boost/asio/ip/udp.hpp>
+#include <boost/asio/local/stream_protocol.hpp>
+
+namespace ndn {
+
+/** \brief represents the underlying protocol and address used by a Face
+ *  \sa https://redmine.named-data.net/projects/nfd/wiki/FaceMgmt#FaceUri
+ */
+class FaceUri
+{
+public:
+  class Error : public std::invalid_argument
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::invalid_argument(what)
+    {
+    }
+  };
+
+  FaceUri();
+
+  /** \brief construct by parsing
+   *
+   *  \param uri scheme://host[:port]/path
+   *  \throw FaceUri::Error if URI cannot be parsed
+   */
+  explicit
+  FaceUri(const std::string& uri);
+
+  // This overload is needed so that calls with string literal won't be
+  // resolved to boost::asio::local::stream_protocol::endpoint overload.
+  explicit
+  FaceUri(const char* uri);
+
+  /// exception-safe parsing
+  bool
+  parse(const std::string& uri);
+
+public: // scheme-specific construction
+  /// construct udp4 or udp6 canonical FaceUri
+  explicit
+  FaceUri(const boost::asio::ip::udp::endpoint& endpoint);
+
+  /// construct tcp4 or tcp6 canonical FaceUri
+  explicit
+  FaceUri(const boost::asio::ip::tcp::endpoint& endpoint);
+
+  /// construct tcp canonical FaceUri with custom scheme
+  FaceUri(const boost::asio::ip::tcp::endpoint& endpoint, const std::string& scheme);
+
+#ifdef BOOST_ASIO_HAS_LOCAL_SOCKETS
+  /// construct unix canonical FaceUri
+  explicit
+  FaceUri(const boost::asio::local::stream_protocol::endpoint& endpoint);
+#endif // BOOST_ASIO_HAS_LOCAL_SOCKETS
+
+  /// create fd FaceUri from file descriptor
+  static FaceUri
+  fromFd(int fd);
+
+  /// construct ether canonical FaceUri
+  explicit
+  FaceUri(const ethernet::Address& address);
+
+  /// create dev FaceUri from network device name
+  static FaceUri
+  fromDev(const std::string& ifname);
+
+  /// create udp4 or udp6 NIC-associated FaceUri from endpoint and network device name
+  static FaceUri
+  fromUdpDev(const boost::asio::ip::udp::endpoint& endpoint, const std::string& ifname);
+
+public: // getters
+  /// get scheme (protocol)
+  const std::string&
+  getScheme() const
+  {
+    return m_scheme;
+  }
+
+  /// get host (domain)
+  const std::string&
+  getHost() const
+  {
+    return m_host;
+  }
+
+  /// get port
+  const std::string&
+  getPort() const
+  {
+    return m_port;
+  }
+
+  /// get path
+  const std::string&
+  getPath() const
+  {
+    return m_path;
+  }
+
+  /// write as a string
+  std::string
+  toString() const;
+
+public: // EqualityComparable concept
+  bool
+  operator==(const FaceUri& rhs) const;
+
+  bool
+  operator!=(const FaceUri& rhs) const;
+
+public: // canonical FaceUri
+  /** \return whether a FaceUri of the scheme can be canonized
+   */
+  static bool
+  canCanonize(const std::string& scheme);
+
+  /** \brief determine whether this FaceUri is in canonical form
+   *  \return true if this FaceUri is in canonical form,
+   *          false if this FaceUri is not in canonical form or
+   *          or it's undetermined whether this FaceUri is in canonical form
+   */
+  bool
+  isCanonical() const;
+
+  typedef function<void(const FaceUri&)> CanonizeSuccessCallback;
+  typedef function<void(const std::string& reason)> CanonizeFailureCallback;
+
+  /** \brief asynchronously convert this FaceUri to canonical form
+   *  \param onSuccess function to call after this FaceUri is converted to canonical form
+   *  \note A new FaceUri in canonical form will be created; this FaceUri is unchanged.
+   *  \param onFailure function to call if this FaceUri cannot be converted to canonical form
+   *  \param io        reference to `boost::asio::io_service` instance
+   *  \param timeout   maximum allowable duration of the operations.
+   *                   It's intentional not to provide a default value: the caller should set
+   *                   a reasonable value in balance between network delay and user experience.
+   */
+  void
+  canonize(const CanonizeSuccessCallback& onSuccess,
+           const CanonizeFailureCallback& onFailure,
+           boost::asio::io_service& io,
+           time::nanoseconds timeout) const;
+
+private:
+  std::string m_scheme;
+  std::string m_host;
+  std::string m_port;
+  std::string m_path;
+  /// whether to add [] around host when writing string
+  bool m_isV6;
+
+  friend std::ostream& operator<<(std::ostream& os, const FaceUri& uri);
+};
+
+std::ostream&
+operator<<(std::ostream& os, const FaceUri& uri);
+
+} // namespace ndn
+
+#endif // NDN_NET_FACE_URI_HPP
diff --git a/src/net/network-address.cpp b/src/net/network-address.cpp
new file mode 100644
index 0000000..148c3ec
--- /dev/null
+++ b/src/net/network-address.cpp
@@ -0,0 +1,60 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2017 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Davide Pesavento <davide.pesavento@lip6.fr>
+ */
+
+#include "network-address.hpp"
+
+namespace ndn {
+namespace net {
+
+std::ostream&
+operator<<(std::ostream& os, AddressScope scope)
+{
+  switch (scope) {
+    case AddressScope::NOWHERE:
+      return os << "nowhere";
+    case AddressScope::HOST:
+      return os << "host";
+    case AddressScope::LINK:
+      return os << "link";
+    case AddressScope::GLOBAL:
+      return os << "global";
+  }
+  return os;
+}
+
+NetworkAddress::NetworkAddress()
+  : m_family(AddressFamily::UNSPECIFIED)
+  , m_flags(0)
+  , m_scope(AddressScope::NOWHERE)
+  , m_prefixLength(0)
+{
+}
+
+std::ostream&
+operator<<(std::ostream& os, const NetworkAddress& addr)
+{
+  return os << addr.getIp() << '/' << static_cast<unsigned int>(addr.getPrefixLength());
+}
+
+} // namespace net
+} // namespace ndn
diff --git a/src/net/network-address.hpp b/src/net/network-address.hpp
new file mode 100644
index 0000000..632a30f
--- /dev/null
+++ b/src/net/network-address.hpp
@@ -0,0 +1,130 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2017 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Davide Pesavento <davide.pesavento@lip6.fr>
+ */
+
+#ifndef NDN_NET_NETWORK_ADDRESS_HPP
+#define NDN_NET_NETWORK_ADDRESS_HPP
+
+#include "network-monitor.hpp"
+
+#include <boost/asio/ip/address.hpp>
+
+namespace ndn {
+namespace net {
+
+enum class AddressFamily {
+  UNSPECIFIED,
+  V4,
+  V6,
+};
+
+enum class AddressScope {
+  NOWHERE,
+  HOST,
+  LINK,
+  GLOBAL,
+};
+
+std::ostream&
+operator<<(std::ostream& os, AddressScope scope);
+
+/**
+ * @brief Stores one IP address supported by a network interface.
+ */
+class NetworkAddress
+{
+public: // getters
+  /** @brief Returns the address family
+   */
+  AddressFamily
+  getFamily() const
+  {
+    return m_family;
+  }
+
+  /** @brief Returns the IP address (v4 or v6)
+   */
+  boost::asio::ip::address
+  getIp() const
+  {
+    return m_ip;
+  }
+
+  /** @brief Returns the IP broadcast address
+   */
+  boost::asio::ip::address
+  getBroadcast() const
+  {
+    return m_broadcast;
+  }
+
+  /** @brief Returns a bitset of platform-specific flags enabled on the address
+   */
+  uint32_t
+  getFlags() const
+  {
+    return m_flags;
+  }
+
+  /** @brief Returns the address scope
+   */
+  AddressScope
+  getScope() const
+  {
+    return m_scope;
+  }
+
+  /** @brief Returns the prefix length
+   */
+  uint8_t
+  getPrefixLength() const
+  {
+    return m_prefixLength;
+  }
+
+  friend bool
+  operator<(const NetworkAddress& a, const NetworkAddress& b)
+  {
+    return a.m_ip < b.m_ip;
+  }
+
+private: // constructor
+  NetworkAddress();
+
+private:
+  friend class NetworkMonitor::Impl;
+
+  AddressFamily m_family;
+  boost::asio::ip::address m_ip;
+  boost::asio::ip::address m_broadcast;
+  uint32_t m_flags; // IFA_F_* in if_addr.h
+  AddressScope m_scope;
+  uint8_t m_prefixLength;
+};
+
+std::ostream&
+operator<<(std::ostream& os, const NetworkAddress& address);
+
+} // namespace net
+} // namespace ndn
+
+#endif // NDN_NET_NETWORK_ADDRESS_HPP
diff --git a/src/net/network-interface.cpp b/src/net/network-interface.cpp
new file mode 100644
index 0000000..a03d850
--- /dev/null
+++ b/src/net/network-interface.cpp
@@ -0,0 +1,240 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2017 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Davide Pesavento <davide.pesavento@lip6.fr>
+ */
+
+#include "network-interface.hpp"
+#include "detail/linux-if-constants.hpp"
+#include "../util/logger.hpp"
+#include "../util/string-helper.hpp"
+
+#include <net/if.h>
+
+NDN_LOG_INIT(ndn.NetworkMonitor);
+
+namespace ndn {
+namespace net {
+
+NetworkInterface::NetworkInterface()
+  : m_index(0)
+  , m_type(InterfaceType::UNKNOWN)
+  , m_flags(0)
+  , m_state(InterfaceState::UNKNOWN)
+  , m_mtu(0)
+{
+}
+
+bool
+NetworkInterface::addNetworkAddress(const NetworkAddress& address)
+{
+  if (!address.getIp().is_unspecified()) {
+    // need to erase the existing address before inserting
+    // because the address flags may have changed
+    bool isNew = m_netAddresses.erase(address) == 0;
+    m_netAddresses.insert(address);
+    if (isNew) {
+      NDN_LOG_DEBUG("added address " << address << " to " << m_name);
+      onAddressAdded(address);
+      return true;
+    }
+  }
+  return false;
+}
+
+bool
+NetworkInterface::removeNetworkAddress(const NetworkAddress& address)
+{
+  if (m_netAddresses.erase(address) > 0) {
+    NDN_LOG_DEBUG("removed address " << address << " from " << m_name);
+    onAddressRemoved(address);
+    return true;
+  }
+  return false;
+}
+
+void
+NetworkInterface::setIndex(int index)
+{
+  m_index = index;
+}
+
+void
+NetworkInterface::setName(const std::string& name)
+{
+  BOOST_ASSERT(!name.empty());
+  m_name = name;
+}
+
+void
+NetworkInterface::setType(InterfaceType type)
+{
+  m_type = type;
+}
+
+void
+NetworkInterface::setFlags(uint32_t flags)
+{
+  m_flags = flags;
+}
+
+void
+NetworkInterface::setState(InterfaceState state)
+{
+  if (m_state != state) {
+    std::swap(m_state, state);
+    onStateChanged(state, m_state);
+  }
+}
+
+void
+NetworkInterface::setMtu(uint32_t mtu)
+{
+  if (m_mtu != mtu) {
+    std::swap(m_mtu, mtu);
+    onMtuChanged(mtu, m_mtu);
+  }
+}
+
+void
+NetworkInterface::setEthernetAddress(const ethernet::Address& address)
+{
+  m_etherAddress = address;
+}
+
+void
+NetworkInterface::setEthernetBroadcastAddress(const ethernet::Address& address)
+{
+  m_etherBrdAddress = address;
+}
+
+std::ostream&
+operator<<(std::ostream& os, InterfaceType type)
+{
+  switch (type) {
+    case InterfaceType::UNKNOWN:
+      return os << "unknown";
+    case InterfaceType::LOOPBACK:
+      return os << "loopback";
+    case InterfaceType::ETHERNET:
+      return os << "ether";
+  }
+  return os;
+}
+
+std::ostream&
+operator<<(std::ostream& os, InterfaceState state)
+{
+  switch (state) {
+    case InterfaceState::UNKNOWN:
+      return os << "unknown";
+    case InterfaceState::DOWN:
+      return os << "down";
+    case InterfaceState::NO_CARRIER:
+      return os << "no-carrier";
+    case InterfaceState::DORMANT:
+      return os << "dormant";
+    case InterfaceState::RUNNING:
+      return os << "running";
+  }
+  return os;
+}
+
+static void
+printFlag(std::ostream& os, uint32_t& flags, uint32_t flagVal, const char* flagStr)
+{
+  if (flags & flagVal) {
+    flags &= ~flagVal;
+    os << flagStr << (flags ? "," : "");
+  }
+}
+
+std::ostream&
+operator<<(std::ostream& os, const NetworkInterface& netif)
+{
+  os << netif.getIndex() << ": " << netif.getName() << ": ";
+
+  auto flags = netif.getFlags();
+  os << "<";
+#define PRINT_IFF(flag) printFlag(os, flags, IFF_##flag, #flag)
+  PRINT_IFF(UP);
+  PRINT_IFF(BROADCAST);
+  PRINT_IFF(DEBUG);
+  PRINT_IFF(LOOPBACK);
+  PRINT_IFF(POINTOPOINT);
+#if defined(IFF_NOTRAILERS)
+  PRINT_IFF(NOTRAILERS);
+#endif
+  PRINT_IFF(RUNNING);
+  PRINT_IFF(NOARP);
+  PRINT_IFF(PROMISC);
+  PRINT_IFF(ALLMULTI);
+  PRINT_IFF(MULTICAST);
+#if defined(__linux__)
+  PRINT_IFF(MASTER);
+  PRINT_IFF(SLAVE);
+  PRINT_IFF(PORTSEL);
+  PRINT_IFF(AUTOMEDIA);
+  PRINT_IFF(DYNAMIC);
+#elif defined(__APPLE__) || defined(__FreeBSD__)
+  PRINT_IFF(OACTIVE);
+  PRINT_IFF(SIMPLEX);
+  PRINT_IFF(LINK0);
+  PRINT_IFF(LINK1);
+  PRINT_IFF(LINK2);
+#endif
+#if defined(__FreeBSD__)
+  PRINT_IFF(CANTCONFIG);
+  PRINT_IFF(PPROMISC);
+  PRINT_IFF(MONITOR);
+  PRINT_IFF(STATICARP);
+  PRINT_IFF(DYING);
+  PRINT_IFF(RENAMING);
+#endif
+#undef PRINT_IFF
+#if defined(__linux__)
+#define PRINT_IF_FLAG(flag) printFlag(os, flags, linux_if::FLAG_##flag, #flag)
+  PRINT_IF_FLAG(LOWER_UP);
+  PRINT_IF_FLAG(DORMANT);
+  PRINT_IF_FLAG(ECHO);
+#undef PRINT_IF_FLAG
+#endif
+  if (flags) {
+    // print unknown flags in hex
+    os << AsHex{flags};
+  }
+  os << ">";
+
+  os << " state " << netif.getState() << " mtu " << netif.getMtu() << "\n"
+     << "    link/" << netif.getType() << " " << netif.getEthernetAddress()
+     << " brd " << netif.getEthernetBroadcastAddress() << "\n";
+
+  for (const auto& addr : netif.getNetworkAddresses()) {
+    os << "    " << (addr.getFamily() == AddressFamily::V4 ? "inet " : "inet6 ") << addr;
+    if (netif.canBroadcast() && !addr.getBroadcast().is_unspecified())
+      os << " brd " << addr.getBroadcast();
+    os << " scope " << addr.getScope() << "\n";
+  }
+
+  return os;
+}
+
+} // namespace net
+} // namespace ndn
diff --git a/src/net/network-interface.hpp b/src/net/network-interface.hpp
new file mode 100644
index 0000000..f5fff7e
--- /dev/null
+++ b/src/net/network-interface.hpp
@@ -0,0 +1,256 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2017 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Davide Pesavento <davide.pesavento@lip6.fr>
+ */
+
+#ifndef NDN_NET_NETWORK_INTERFACE_HPP
+#define NDN_NET_NETWORK_INTERFACE_HPP
+
+#include "ethernet.hpp"
+#include "network-address.hpp"
+#include "network-monitor.hpp"
+#include "../util/signal.hpp"
+
+#include <set>
+
+namespace ndn {
+namespace net {
+
+/** @brief Indicates the hardware type of a network interface
+ */
+enum class InterfaceType {
+  UNKNOWN,
+  LOOPBACK,
+  ETHERNET,
+  // we do not support anything else for now
+};
+
+std::ostream&
+operator<<(std::ostream& os, InterfaceType type);
+
+/** @brief Indicates the state of a network interface
+ */
+enum class InterfaceState {
+  UNKNOWN,    ///< interface is in an unknown state
+  DOWN,       ///< interface is administratively down
+  NO_CARRIER, ///< interface is administratively up but has no carrier
+  DORMANT,    ///< interface has a carrier but it cannot send or receive normal user traffic yet
+  RUNNING,    ///< interface can be used to send and receive packets
+};
+
+std::ostream&
+operator<<(std::ostream& os, InterfaceState state);
+
+/**
+ * @brief Represents one network interface attached to the host.
+ *
+ * Each network interface has a unique index, a name, and a set of flags indicating its
+ * capabilities and current state. It may contain one hardware (Ethernet) address, and
+ * zero or more network-layer (IP) addresses. Specific signals are emitted when the
+ * interface data change.
+ */
+class NetworkInterface
+{
+public: // signals
+  /** @brief Fires when interface state changes
+   */
+  util::Signal<NetworkInterface, InterfaceState /*old*/, InterfaceState /*new*/> onStateChanged;
+
+  /** @brief Fires when interface mtu changes
+   */
+  util::Signal<NetworkInterface, uint32_t /*old*/, uint32_t /*new*/> onMtuChanged;
+
+  /** @brief Fires when a network-layer address is added to the interface
+   */
+  util::Signal<NetworkInterface, NetworkAddress> onAddressAdded;
+
+  /** @brief Fires when a network-layer address is removed from the interface
+   */
+  util::Signal<NetworkInterface, NetworkAddress> onAddressRemoved;
+
+public: // getters
+  /** @brief Returns an opaque ID that uniquely identifies the interface on the system
+   */
+  int
+  getIndex() const
+  {
+    return m_index;
+  }
+
+  /** @brief Returns the name of the interface, unique on the system
+   */
+  std::string
+  getName() const
+  {
+    return m_name;
+  }
+
+  /** @brief Returns the hardware type of the interface
+   */
+  InterfaceType
+  getType() const
+  {
+    return m_type;
+  }
+
+  /** @brief Returns a bitset of platform-specific flags enabled on the interface
+   */
+  uint32_t
+  getFlags() const
+  {
+    return m_flags;
+  }
+
+  /** @brief Returns the current state of the interface
+   */
+  InterfaceState
+  getState() const
+  {
+    return m_state;
+  }
+
+  /** @brief Returns the MTU (maximum transmission unit) of the interface
+   */
+  uint32_t
+  getMtu() const
+  {
+    return m_mtu;
+  }
+
+  /** @brief Returns the link-layer (Ethernet) address of the interface
+   */
+  ethernet::Address
+  getEthernetAddress() const
+  {
+    return m_etherAddress;
+  }
+
+  /** @brief Returns the link-layer (Ethernet) broadcast address of the interface
+   */
+  ethernet::Address
+  getEthernetBroadcastAddress() const
+  {
+    return m_etherBrdAddress;
+  }
+
+  /** @brief Returns a list of all network-layer addresses present on the interface
+   */
+  const std::set<NetworkAddress>&
+  getNetworkAddresses() const
+  {
+    return m_netAddresses;
+  }
+
+  /** @brief Returns true if the interface is a loopback interface
+   */
+  bool
+  isLoopback() const
+  {
+    return (m_flags & IFF_LOOPBACK) != 0;
+  }
+
+  /** @brief Returns true if the interface is a point-to-point interface
+   */
+  bool
+  isPointToPoint() const
+  {
+    return (m_flags & IFF_POINTOPOINT) != 0;
+  }
+
+  /** @brief Returns true if the interface supports broadcast communication
+   */
+  bool
+  canBroadcast() const
+  {
+    return (m_flags & IFF_BROADCAST) != 0;
+  }
+
+  /** @brief Returns true if the interface supports multicast communication
+   */
+  bool
+  canMulticast() const
+  {
+    return (m_flags & IFF_MULTICAST) != 0;
+  }
+
+  /** @brief Returns true if the interface is administratively up
+   */
+  bool
+  isUp() const
+  {
+    return (m_flags & IFF_UP) != 0;
+  }
+
+private: // constructor
+  NetworkInterface();
+
+private: // modifiers
+  bool
+  addNetworkAddress(const NetworkAddress& address);
+
+  bool
+  removeNetworkAddress(const NetworkAddress& address);
+
+  void
+  setIndex(int index);
+
+  void
+  setName(const std::string& name);
+
+  void
+  setType(InterfaceType type);
+
+  void
+  setFlags(uint32_t flags);
+
+  void
+  setState(InterfaceState state);
+
+  void
+  setMtu(uint32_t mtu);
+
+  void
+  setEthernetAddress(const ethernet::Address& address);
+
+  void
+  setEthernetBroadcastAddress(const ethernet::Address& address);
+
+private:
+  friend class NetworkMonitor::Impl;
+
+  int m_index;
+  std::string m_name;
+  InterfaceType m_type;
+  uint32_t m_flags; // IFF_* in <net/if.h>
+  InterfaceState m_state;
+  uint32_t m_mtu;
+  ethernet::Address m_etherAddress;
+  ethernet::Address m_etherBrdAddress;
+  std::set<NetworkAddress> m_netAddresses;
+};
+
+std::ostream&
+operator<<(std::ostream& os, const NetworkInterface& interface);
+
+} // namespace net
+} // namespace ndn
+
+#endif // NDN_NET_NETWORK_INTERFACE_HPP
diff --git a/src/net/network-monitor.cpp b/src/net/network-monitor.cpp
new file mode 100644
index 0000000..c4a2e2e
--- /dev/null
+++ b/src/net/network-monitor.cpp
@@ -0,0 +1,65 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2017 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ * @author Davide Pesavento <davide.pesavento@lip6.fr>
+ */
+
+#include "network-monitor.hpp"
+#include "ndn-cxx-config.hpp"
+
+#if defined(NDN_CXX_HAVE_OSX_FRAMEWORKS)
+#include "detail/network-monitor-impl-osx.hpp"
+#elif defined(NDN_CXX_HAVE_RTNETLINK)
+#include "detail/network-monitor-impl-rtnl.hpp"
+#else
+#include "detail/network-monitor-impl-noop.hpp"
+#endif
+
+namespace ndn {
+namespace net {
+
+NetworkMonitor::NetworkMonitor(boost::asio::io_service& io)
+  : m_impl(make_unique<Impl>(*this, io))
+{
+}
+
+NetworkMonitor::~NetworkMonitor() = default;
+
+uint32_t
+NetworkMonitor::getCapabilities() const
+{
+  return m_impl->getCapabilities();
+}
+
+shared_ptr<NetworkInterface>
+NetworkMonitor::getNetworkInterface(const std::string& ifname) const
+{
+  return m_impl->getNetworkInterface(ifname);
+}
+
+std::vector<shared_ptr<NetworkInterface>>
+NetworkMonitor::listNetworkInterfaces() const
+{
+  return m_impl->listNetworkInterfaces();
+}
+
+} // namespace net
+} // namespace ndn
diff --git a/src/net/network-monitor.hpp b/src/net/network-monitor.hpp
new file mode 100644
index 0000000..f3326b7
--- /dev/null
+++ b/src/net/network-monitor.hpp
@@ -0,0 +1,135 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2017 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ * @author Davide Pesavento <davide.pesavento@lip6.fr>
+ */
+
+#ifndef NDN_NET_NETWORK_MONITOR_HPP
+#define NDN_NET_NETWORK_MONITOR_HPP
+
+#include "../util/signal.hpp"
+
+#include <vector>
+
+// forward declaration
+namespace boost {
+namespace asio {
+class io_service;
+} // namespace asio
+} // namespace boost
+
+namespace ndn {
+namespace net {
+
+class NetworkInterface;
+
+/**
+ * @brief Network interfaces monitor
+ *
+ * Maintains an up-to-date view of every system network interface and notifies when an interface
+ * is added or removed.
+ *
+ * @note Implementation of this class is platform dependent and not all supported platforms
+ *       are supported:
+ *       - OS X: SystemConfiguration and CFNotificationCenterAddObserver notifications (no
+ *         notification on MTU change)
+ *       - Linux: rtnetlink notifications
+ */
+class NetworkMonitor : noncopyable
+{
+public:
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+  class Impl;
+
+  /**
+   * @brief Construct instance, request enumeration of all network interfaces, and start
+   *        monitoring for network state changes
+   *
+   * @param io io_service thread that will dispatch events
+   * @throw Error when network monitoring is not supported or there is an error starting monitoring
+   */
+  explicit
+  NetworkMonitor(boost::asio::io_service& io);
+
+  ~NetworkMonitor();
+
+  enum Capability : uint32_t {
+    /// NetworkMonitor is not supported and is a no-op
+    CAP_NONE = 0,
+    /// listNetworkInterfaces() and getNetworkInterface() are supported
+    CAP_ENUM = 1 << 0,
+    /// NetworkMonitor onInterfaceAdded and onInterfaceRemoved signals are supported
+    CAP_IF_ADD_REMOVE = 1 << 1,
+    /// NetworkInterface onStateChanged signal is supported
+    CAP_STATE_CHANGE = 1 << 2,
+    /// NetworkInterface onMtuChanged signal is supported
+    CAP_MTU_CHANGE = 1 << 3,
+    /// NetworkInterface onAddressAdded and onAddressRemoved signals are supported
+    CAP_ADDR_ADD_REMOVE = 1 << 4
+  };
+
+  /** \return bitwise OR'ed \p Capability supported on current platform
+   */
+  uint32_t
+  getCapabilities() const;
+
+  shared_ptr<NetworkInterface>
+  getNetworkInterface(const std::string& ifname) const;
+
+  std::vector<shared_ptr<NetworkInterface>>
+  listNetworkInterfaces() const;
+
+public: // signals
+  /** @brief Fires when network interfaces enumeration is complete
+   */
+  util::Signal<NetworkMonitor> onEnumerationCompleted;
+
+  /** @brief Fires when a new interface is added
+   */
+  util::Signal<NetworkMonitor, shared_ptr<NetworkInterface>> onInterfaceAdded;
+
+  /**
+   * @brief Fires when an interface is removed
+   * @note The NetworkInterface object is no longer present in the network
+   *       interfaces map when the signal is emitted
+   */
+  util::Signal<NetworkMonitor, shared_ptr<NetworkInterface>> onInterfaceRemoved;
+
+  // only for backward compatibility
+  util::Signal<NetworkMonitor> onNetworkStateChanged;
+
+private:
+  const unique_ptr<Impl> m_impl;
+};
+
+} // namespace net
+} // namespace ndn
+
+#endif // NDN_NET_NETWORK_MONITOR_HPP
