diff --git a/tools/ndn-autoconfig.cpp b/tools/ndn-autoconfig.cpp
deleted file mode 100644
index 09f5dba..0000000
--- a/tools/ndn-autoconfig.cpp
+++ /dev/null
@@ -1,537 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  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 NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "version.hpp"
-
-#include <ndn-cxx/face.hpp>
-#include <ndn-cxx/security/key-chain.hpp>
-#include <ndn-cxx/management/nfd-controller.hpp>
-#include <ndn-cxx/management/nfd-face-status.hpp>
-#include <ndn-cxx/security/key-chain.hpp>
-#include <ndn-cxx/encoding/buffer-stream.hpp>
-#include <ndn-cxx/util/face-uri.hpp>
-
-#include <boost/lexical_cast.hpp>
-#include <boost/noncopyable.hpp>
-
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/nameser.h>
-#include <resolv.h>
-
-#ifdef __APPLE__
-#include <arpa/nameser_compat.h>
-#endif
-
-namespace ndn {
-namespace tools {
-
-static const Name LOCALHOP_HUB_DISCOVERY_PREFIX = "/localhop/ndn-autoconf/hub";
-
-void
-usage(const char* programName)
-{
-  std::cout << "Usage:\n" << programName  << " [-h] [-V]\n"
-            << "   -h  - print usage and exit\n"
-            << "   -V  - print version number and exit\n"
-            << std::endl;
-}
-
-class NdnAutoconfig : boost::noncopyable
-{
-public:
-  union QueryAnswer
-  {
-    HEADER header;
-    uint8_t buf[NS_PACKETSZ];
-  };
-
-  class Error : public std::runtime_error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : std::runtime_error(what)
-    {
-    }
-  };
-
-  explicit
-  NdnAutoconfig()
-    : m_controller(m_face, m_keyChain)
-  {
-  }
-
-  void
-  run()
-  {
-    m_face.processEvents();
-  }
-
-  void
-  fetchSegments(const Data& data, const shared_ptr<OBufferStream>& buffer,
-                void (NdnAutoconfig::*onDone)(const shared_ptr<OBufferStream>&))
-  {
-    buffer->write(reinterpret_cast<const char*>(data.getContent().value()),
-                  data.getContent().value_size());
-
-    uint64_t currentSegment = data.getName().get(-1).toSegment();
-
-    const name::Component& finalBlockId = data.getMetaInfo().getFinalBlockId();
-    if (finalBlockId.empty() ||
-        finalBlockId.toSegment() > currentSegment)
-      {
-        m_face.expressInterest(data.getName().getPrefix(-1).appendSegment(currentSegment+1),
-                               ndn::bind(&NdnAutoconfig::fetchSegments, this, _2, buffer, onDone),
-                               ndn::bind(&NdnAutoconfig::discoverHubStage2, this, "Timeout"));
-      }
-    else
-      {
-        return (this->*onDone)(buffer);
-      }
-  }
-
-  void
-  discoverHubStage1()
-  {
-    shared_ptr<OBufferStream> buffer = make_shared<OBufferStream>();
-
-    Interest interest("/localhost/nfd/faces/list");
-    interest.setChildSelector(1);
-    interest.setMustBeFresh(true);
-
-    m_face.expressInterest(interest,
-                           ndn::bind(&NdnAutoconfig::fetchSegments, this, _2, buffer,
-                                     &NdnAutoconfig::discoverHubStage1_registerHubDiscoveryPrefix),
-                           ndn::bind(&NdnAutoconfig::discoverHubStage2, this, "Timeout"));
-  }
-
-  void
-  discoverHubStage1_registerHubDiscoveryPrefix(const shared_ptr<OBufferStream>& buffer)
-  {
-    ConstBufferPtr buf = buffer->buf();
-    std::vector<uint64_t> multicastFaces;
-
-    size_t offset = 0;
-    while (offset < buf->size())
-      {
-        Block block;
-        bool ok = Block::fromBuffer(buf, offset, block);
-        if (!ok)
-          {
-            std::cerr << "ERROR: cannot decode FaceStatus TLV" << std::endl;
-            break;
-          }
-
-        offset += block.size();
-
-        nfd::FaceStatus faceStatus(block);
-
-        ndn::util::FaceUri uri(faceStatus.getRemoteUri());
-        if (uri.getScheme() == "udp4") {
-          namespace ip = boost::asio::ip;
-          boost::system::error_code ec;
-          ip::address address = ip::address::from_string(uri.getHost(), ec);
-
-          if (!ec && address.is_multicast()) {
-            multicastFaces.push_back(faceStatus.getFaceId());
-          }
-          else
-            continue;
-        }
-      }
-
-    if (multicastFaces.empty()) {
-      discoverHubStage2("No multicast faces available, skipping stage 1");
-    }
-    else {
-      shared_ptr<nfd::Controller> controller = make_shared<nfd::Controller>(ref(m_face));
-      shared_ptr<std::pair<size_t, size_t> > nRegistrations =
-        make_shared<std::pair<size_t, size_t> >(0, 0);
-
-      nfd::ControlParameters parameters;
-      parameters
-        .setName(LOCALHOP_HUB_DISCOVERY_PREFIX)
-        .setCost(1)
-        .setExpirationPeriod(time::seconds(30));
-
-      nRegistrations->first = multicastFaces.size();
-
-      for (std::vector<uint64_t>::iterator i = multicastFaces.begin();
-           i != multicastFaces.end(); ++i) {
-        parameters.setFaceId(*i);
-
-        controller->start<nfd::RibRegisterCommand>(parameters,
-          bind(&NdnAutoconfig::discoverHubStage1_onRegisterSuccess,
-               this, controller, nRegistrations),
-          bind(&NdnAutoconfig::discoverHubStage1_onRegisterFailure,
-               this, _1, _2, controller, nRegistrations));
-      }
-    }
-  }
-
-  void
-  discoverHubStage1_onRegisterSuccess(const shared_ptr<nfd::Controller>& controller,
-                                      const shared_ptr<std::pair<size_t, size_t> >& nRegistrations)
-  {
-    nRegistrations->second++;
-
-    if (nRegistrations->first == nRegistrations->second) {
-      discoverHubStage1_setStrategy(controller);
-    }
-  }
-
-  void
-  discoverHubStage1_onRegisterFailure(uint32_t code, const std::string& error,
-                                      const shared_ptr<nfd::Controller>& controller,
-                                      const shared_ptr<std::pair<size_t, size_t> >& nRegistrations)
-  {
-    std::cerr << "ERROR: " << error << " (code: " << code << ")" << std::endl;
-    nRegistrations->first--;
-
-    if (nRegistrations->first == nRegistrations->second) {
-      if (nRegistrations->first > 0) {
-        discoverHubStage1_setStrategy(controller);
-      } else {
-        discoverHubStage2("Failed to register " + LOCALHOP_HUB_DISCOVERY_PREFIX.toUri() +
-                          " for all multicast faces");
-      }
-    }
-  }
-
-  void
-  discoverHubStage1_setStrategy(const shared_ptr<nfd::Controller>& controller)
-  {
-    nfd::ControlParameters parameters;
-    parameters
-      .setName(LOCALHOP_HUB_DISCOVERY_PREFIX)
-      .setStrategy("/localhost/nfd/strategy/broadcast");
-
-    controller->start<nfd::StrategyChoiceSetCommand>(parameters,
-      bind(&NdnAutoconfig::discoverHubStage1_onSetStrategySuccess,
-           this, controller),
-      bind(&NdnAutoconfig::discoverHubStage1_onSetStrategyFailure,
-           this, _2, controller));
-  }
-
-  void
-  discoverHubStage1_onSetStrategySuccess(const shared_ptr<nfd::Controller>& controller)
-  {
-    discoverHubStage1_requestHubData();
-  }
-
-  void
-  discoverHubStage1_onSetStrategyFailure(const std::string& error,
-                                         const shared_ptr<nfd::Controller>& controller)
-  {
-    discoverHubStage2("Failed to set broadcast strategy for " +
-                      LOCALHOP_HUB_DISCOVERY_PREFIX.toUri() + " namespace (" + error + ")");
-  }
-
-  // Start to look for a hub (NDN hub discovery first stage)
-  void
-  discoverHubStage1_requestHubData()
-  {
-    Interest interest(LOCALHOP_HUB_DISCOVERY_PREFIX);
-    interest.setInterestLifetime(time::milliseconds(4000)); // 4 seconds
-    interest.setMustBeFresh(true);
-
-    std::cerr << "Stage 1: Trying multicast discovery..." << std::endl;
-    m_face.expressInterest(interest,
-                           bind(&NdnAutoconfig::onDiscoverHubStage1Success, this, _1, _2),
-                           bind(&NdnAutoconfig::discoverHubStage2, this, "Timeout"));
-  }
-
-  // First stage OnData Callback
-  void
-  onDiscoverHubStage1Success(const Interest& interest, Data& data)
-  {
-    const Block& content = data.getContent();
-    content.parse();
-
-    // Get Uri
-    Block::element_const_iterator blockValue = content.find(tlv::nfd::Uri);
-    if (blockValue == content.elements_end()) {
-      discoverHubStage2("Incorrect reply to stage1");
-      return;
-    }
-    std::string faceMgmtUri(reinterpret_cast<const char*>(blockValue->value()),
-                            blockValue->value_size());
-    connectToHub(faceMgmtUri);
-  }
-
-  // First stage OnTimeout callback - start 2nd stage
-  void
-  discoverHubStage2(const std::string& message)
-  {
-    std::cerr << message << std::endl;
-    std::cerr << "Stage 2: Trying DNS query with default suffix..." << std::endl;
-
-    _res.retry = 2;
-    _res.ndots = 10;
-
-    QueryAnswer queryAnswer;
-
-    int answerSize = res_search("_ndn._udp",
-                                ns_c_in,
-                                ns_t_srv,
-                                queryAnswer.buf,
-                                sizeof(queryAnswer));
-
-    // 2nd stage failed - move on to the third stage
-    if (answerSize < 0) {
-      discoverHubStage3("Failed to find NDN router using default suffix DNS query");
-    }
-    else
-    {
-      bool isParsed = parseHostAndConnectToHub(queryAnswer, answerSize);
-      if (isParsed == false) {
-        // Failed to parse DNS response, try stage 3
-        discoverHubStage3("Failed to parse DNS response");
-      }
-    }
-  }
-
-  // Second stage OnTimeout callback
-  void
-  discoverHubStage3(const std::string& message)
-  {
-    std::cerr << message << std::endl;
-    std::cerr << "Stage 3: Trying to find home router..." << std::endl;
-
-    KeyChain keyChain;
-    Name identity = keyChain.getDefaultIdentity();
-    std::string serverName = "_ndn._udp.";
-
-    for (Name::const_reverse_iterator i = identity.rbegin(); i != identity.rend(); i++) {
-      serverName.append(i->toUri());
-      serverName.append(".");
-    }
-    serverName += "_homehub._autoconf.named-data.net";
-    std::cerr << "Stage3: About to query for a home router: " << serverName << std::endl;
-
-    QueryAnswer queryAnswer;
-
-    int answerSize = res_query(serverName.c_str(),
-                               ns_c_in,
-                               ns_t_srv,
-                               queryAnswer.buf,
-                               sizeof(queryAnswer));
-
-
-    // 3rd stage failed - abort
-    if (answerSize < 0) {
-      std::cerr << "Failed to find a home router" << std::endl;
-      std::cerr << "exit" << std::endl;
-    }
-    else
-    {
-      bool isParsed = parseHostAndConnectToHub(queryAnswer, answerSize);
-      if (isParsed == false) {
-        // Failed to parse DNS response
-        throw Error("Failed to parse DNS response");
-      }
-    }
-
-  }
-
-  bool
-  parseHostAndConnectToHub(QueryAnswer& queryAnswer, int answerSize)
-  {
-    // The references of the next classes are:
-    // http://www.diablotin.com/librairie/networking/dnsbind/ch14_02.htm
-    // https://gist.github.com/mologie/6027597
-
-    struct rechdr
-    {
-      uint16_t type;
-      uint16_t iclass;
-      uint32_t ttl;
-      uint16_t length;
-    };
-
-    struct srv_t
-    {
-      uint16_t priority;
-      uint16_t weight;
-      uint16_t port;
-      uint8_t* target;
-    };
-
-    if (ntohs(queryAnswer.header.ancount) == 0) {
-      std::cerr << "No records found\n" << std::endl;
-      return false;
-    }
-
-    uint8_t* blob = queryAnswer.buf + NS_HFIXEDSZ;
-
-    blob += dn_skipname(blob, queryAnswer.buf + answerSize) + NS_QFIXEDSZ;
-
-    for (int i = 0; i < ntohs(queryAnswer.header.ancount); i++) {
-      char srvName[NS_MAXDNAME];
-      int serverNameSize = dn_expand(queryAnswer.buf,               // message pointer
-                                     queryAnswer.buf + answerSize,  // end of message
-                                     blob,                          // compressed server name
-                                     srvName,                       // expanded server name
-                                     NS_MAXDNAME);
-      if (serverNameSize < 0) {
-        return false;
-      }
-
-      srv_t* server = reinterpret_cast<srv_t*>(&blob[sizeof(rechdr)]);
-      uint16_t convertedPort = be16toh(server->port);
-
-      blob += serverNameSize + NS_HFIXEDSZ + NS_QFIXEDSZ;
-
-      char hostName[NS_MAXDNAME];
-      int hostNameSize = dn_expand(queryAnswer.buf,               // message pointer
-                                   queryAnswer.buf + answerSize,  // end of message
-                                   blob,                          // compressed host name
-                                   hostName,                      // expanded host name
-                                   NS_MAXDNAME);
-      if (hostNameSize < 0) {
-        return false;
-      }
-
-      std::string uri = "udp://";
-      uri.append(hostName);
-      uri.append(":");
-      uri.append(boost::lexical_cast<std::string>(convertedPort));
-
-      connectToHub(uri);
-
-      return true;
-    }
-    return false;
-  }
-
-  void
-  connectToHub(const std::string& uri)
-  {
-    ndn::util::FaceUri faceUri(uri);
-
-    faceUri.canonize(bind(&NdnAutoconfig::onCanonizeSuccess, this, _1),
-                     bind(&NdnAutoconfig::onCanonizeFailure, this, _1),
-                     m_face.getIoService(), ndn::time::seconds(4));
-
-  }
-
-  void onCanonizeSuccess(const ndn::util::FaceUri& canonicalUri)
-  {
-    std::cerr << "about to connect to: " << canonicalUri.toString() << std::endl;
-
-    m_controller.start<nfd::FaceCreateCommand>(
-      nfd::ControlParameters()
-        .setUri(canonicalUri.toString()),
-      bind(&NdnAutoconfig::onHubConnectSuccess, this, _1),
-      bind(&NdnAutoconfig::onHubConnectError, this, _1, _2));
-  }
-
-  void
-  onCanonizeFailure(const std::string& reason)
-  {
-    std::ostringstream os;
-    os << "Canonize faceUri failed: " << reason;
-    throw Error(os.str());
-  }
-
-  void
-  onHubConnectSuccess(const nfd::ControlParameters& resp)
-  {
-    std::cerr << "Successfully created face: " << resp << std::endl;
-
-    // Register a prefix in RIB
-    static const Name TESTBED_PREFIX("/ndn");
-    m_controller.start<nfd::RibRegisterCommand>(
-      nfd::ControlParameters()
-        .setName(TESTBED_PREFIX)
-        .setFaceId(resp.getFaceId())
-        .setOrigin(nfd::ROUTE_ORIGIN_AUTOCONF)
-        .setCost(100)
-        .setExpirationPeriod(time::milliseconds::max()),
-      bind(&NdnAutoconfig::onPrefixRegistrationSuccess, this, _1),
-      bind(&NdnAutoconfig::onPrefixRegistrationError, this, _1, _2));
-  }
-
-  void
-  onHubConnectError(uint32_t code, const std::string& error)
-  {
-    std::ostringstream os;
-    os << "Failed to create face: " << error << " (code: " << code << ")";
-    throw Error(os.str());
-  }
-
-  void
-  onPrefixRegistrationSuccess(const nfd::ControlParameters& commandSuccessResult)
-  {
-    std::cerr << "Successful in name registration: " << commandSuccessResult << std::endl;
-  }
-
-  void
-  onPrefixRegistrationError(uint32_t code, const std::string& error)
-  {
-    std::ostringstream os;
-    os << "Failed in name registration, " << error << " (code: " << code << ")";
-    throw Error(os.str());
-  }
-
-private:
-  Face m_face;
-  KeyChain m_keyChain;
-  nfd::Controller m_controller;
-};
-
-} // namespace tools
-} // namespace ndn
-
-int
-main(int argc, char** argv)
-{
-  int opt;
-  const char* programName = argv[0];
-
-  while ((opt = getopt(argc, argv, "hV")) != -1) {
-    switch (opt) {
-    case 'h':
-      ndn::tools::usage(programName);
-      return 0;
-    case 'V':
-      std::cout << NFD_VERSION_BUILD_STRING << std::endl;
-      return 0;
-    }
-  }
-
-  try {
-    ndn::tools::NdnAutoconfig autoConfigInstance;
-
-    autoConfigInstance.discoverHubStage1();
-    autoConfigInstance.run();
-  }
-  catch (const std::exception& error) {
-    std::cerr << "ERROR: " << error.what() << std::endl;
-    return 1;
-  }
-  return 0;
-}
diff --git a/tools/ndn-autoconfig/base-dns.cpp b/tools/ndn-autoconfig/base-dns.cpp
new file mode 100644
index 0000000..23e8782
--- /dev/null
+++ b/tools/ndn-autoconfig/base-dns.cpp
@@ -0,0 +1,161 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  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 NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "base-dns.hpp"
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <resolv.h>
+#include <arpa/nameser.h>
+
+#ifdef __APPLE__
+#include <arpa/nameser_compat.h>
+#endif
+
+namespace ndn {
+namespace tools {
+namespace autoconfig {
+
+union BaseDns::QueryAnswer
+{
+  HEADER header;
+  uint8_t buf[NS_PACKETSZ];
+};
+
+BaseDns::BaseDns(Face& face, KeyChain& keyChain, const NextStageCallback& nextStageOnFailure)
+  : Base(face, keyChain, nextStageOnFailure)
+{
+}
+
+std::string
+BaseDns::querySrvRr(const std::string& fqdn)
+{
+  std::string srvDomain = "_ndn._udp." + fqdn;
+  std::cerr << "Sending DNS query for SRV record for " << srvDomain << std::endl;
+
+  QueryAnswer queryAnswer;
+  int answerSize = res_query(srvDomain.c_str(),
+                             ns_c_in,
+                             ns_t_srv,
+                             queryAnswer.buf,
+                             sizeof(queryAnswer));
+  if (answerSize == 0) {
+    throw Error("No DNS SRV records found for " + srvDomain);
+  }
+  return parseSrvRr(queryAnswer, answerSize);
+}
+
+/**
+ * @brief Send DNS SRV request using search domain list
+ */
+std::string
+BaseDns::querySrvRrSearch()
+{
+  std::cerr << "Sending DNS query for SRV record for _ndn._udp" << std::endl;
+
+  QueryAnswer queryAnswer;
+
+  _res.retry = 2;
+  _res.ndots = 10;
+
+  int answerSize = res_search("_ndn._udp",
+                              ns_c_in,
+                              ns_t_srv,
+                              queryAnswer.buf,
+                              sizeof(queryAnswer));
+
+  if (answerSize == 0) {
+    throw Error("No DNS SRV records found for _ndn._udp");
+  }
+
+  return parseSrvRr(queryAnswer, answerSize);
+}
+
+std::string
+BaseDns::parseSrvRr(const QueryAnswer& queryAnswer, int answerSize)
+{
+  // The references of the next classes are:
+  // http://www.diablotin.com/librairie/networking/dnsbind/ch14_02.htm
+
+  struct rechdr
+  {
+    uint16_t type;
+    uint16_t iclass;
+    uint32_t ttl;
+    uint16_t length;
+  };
+
+  struct srv_t
+  {
+    uint16_t priority;
+    uint16_t weight;
+    uint16_t port;
+    uint8_t* target;
+  };
+
+  if (ntohs(queryAnswer.header.ancount) == 0) {
+    throw Error("SRV record cannot be parsed");
+  }
+
+  const uint8_t* blob = queryAnswer.buf + NS_HFIXEDSZ;
+
+  blob += dn_skipname(blob, queryAnswer.buf + answerSize) + NS_QFIXEDSZ;
+
+  char srvName[NS_MAXDNAME];
+  int serverNameSize = dn_expand(queryAnswer.buf,               // message pointer
+                                 queryAnswer.buf + answerSize,  // end of message
+                                 blob,                          // compressed server name
+                                 srvName,                       // expanded server name
+                                 NS_MAXDNAME);
+  if (serverNameSize <= 0) {
+    throw Error("SRV record cannot be parsed (error decoding domain name)");
+  }
+
+  const srv_t* server = reinterpret_cast<const srv_t*>(&blob[sizeof(rechdr)]);
+  uint16_t convertedPort = be16toh(server->port);
+
+  blob += serverNameSize + NS_HFIXEDSZ + NS_QFIXEDSZ;
+
+  char hostName[NS_MAXDNAME];
+  int hostNameSize = dn_expand(queryAnswer.buf,               // message pointer
+                               queryAnswer.buf + answerSize,  // end of message
+                               blob,                          // compressed host name
+                               hostName,                      // expanded host name
+                               NS_MAXDNAME);
+  if (hostNameSize <= 0) {
+    throw Error("SRV record cannot be parsed (error decoding host name)");
+  }
+
+  std::string uri = "udp://";
+  uri.append(hostName);
+  uri.append(":");
+  uri.append(std::to_string(convertedPort));
+
+  return uri;
+}
+
+} // namespace autoconfig
+} // namespace tools
+} // namespace ndn
diff --git a/tools/ndn-autoconfig/base-dns.hpp b/tools/ndn-autoconfig/base-dns.hpp
new file mode 100644
index 0000000..1b881ba
--- /dev/null
+++ b/tools/ndn-autoconfig/base-dns.hpp
@@ -0,0 +1,85 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  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 NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_TOOLS_NDN_AUTOCONFIG_BASE_DNS_HPP
+#define NFD_TOOLS_NDN_AUTOCONFIG_BASE_DNS_HPP
+
+#include "base.hpp"
+
+namespace ndn {
+namespace tools {
+namespace autoconfig {
+
+/**
+ * @brief Base class for stages that use DNS-based guessing
+ */
+class BaseDns : public Base
+{
+protected:
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+  BaseDns(Face& face, KeyChain& keyChain, const NextStageCallback& nextStageOnFailure);
+
+  /**
+   * @brief Send DNS SRV request for a @p fqdn fully qualified domain name
+   * @return FaceUri of the hub from the requested SRV record
+   * @throw Error if query returns nothing or SRV record cannot be parsed
+   */
+  std::string
+  querySrvRr(const std::string& fqdn);
+
+  /**
+   * @brief Send DNS SRV request using search domain list
+   * @return FaceUri of the hub from the requested SRV record
+   * @throw Error if query returns nothing or SRV record cannot be parsed
+   */
+  std::string
+  querySrvRrSearch();
+
+private:
+  union QueryAnswer;
+
+  /**
+   * @brief Parse SRV record
+   * @return FaceUri of the hub from the SRV record
+   * @throw Error if SRV record cannot be parsed
+   */
+  std::string
+  parseSrvRr(const QueryAnswer& queryAnswer, int answerSize);
+};
+
+} // namespace autoconfig
+} // namespace tools
+} // namespace ndn
+
+#endif // NFD_TOOLS_NDN_AUTOCONFIG_BASE_DNS_HPP
diff --git a/tools/ndn-autoconfig/base.cpp b/tools/ndn-autoconfig/base.cpp
new file mode 100644
index 0000000..ed051e1
--- /dev/null
+++ b/tools/ndn-autoconfig/base.cpp
@@ -0,0 +1,119 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  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 NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "base.hpp"
+
+namespace ndn {
+namespace tools {
+namespace autoconfig {
+
+Base::Base(Face& face, KeyChain& keyChain, const NextStageCallback& nextStageOnFailure)
+  : m_face(face)
+  , m_keyChain(keyChain)
+  , m_controller(face, keyChain)
+  , m_nextStageOnFailure(nextStageOnFailure)
+{
+}
+
+void
+Base::connectToHub(const std::string& uri)
+{
+  util::FaceUri faceUri(uri);
+
+  faceUri.canonize(bind(&Base::onCanonizeSuccess, this, _1),
+                   bind(&Base::onCanonizeFailure, this, _1),
+                   m_face.getIoService(), time::seconds(4));
+
+}
+
+
+void
+Base::onCanonizeSuccess(const util::FaceUri& canonicalUri)
+{
+  std::cerr << "About to connect to: " << canonicalUri.toString() << std::endl;
+
+  m_controller.start<nfd::FaceCreateCommand>(nfd::ControlParameters()
+                                               .setUri(canonicalUri.toString()),
+                                             bind(&Base::onHubConnectSuccess, this, _1),
+                                             bind(&Base::onHubConnectError, this, _1, _2));
+}
+
+void
+Base::onCanonizeFailure(const std::string& reason)
+{
+  std::ostringstream os;
+  os << "FaceUri canonization failed: " << reason;
+  throw Error(os.str());
+}
+
+void
+Base::onHubConnectSuccess(const nfd::ControlParameters& resp)
+{
+  std::cerr << "Successfully created face: " << resp << std::endl;
+
+  static const Name TESTBED_PREFIX = "/ndn";
+  registerPrefix(TESTBED_PREFIX, resp.getFaceId());
+}
+
+void
+Base::onHubConnectError(uint32_t code, const std::string& error)
+{
+  std::ostringstream os;
+  os << "Failed to create face: " << error << " (code: " << code << ")";
+  throw Error(os.str());
+}
+
+void
+Base::registerPrefix(const Name& prefix, uint64_t faceId)
+{
+  // Register a prefix in RIB
+  m_controller.start<nfd::RibRegisterCommand>(nfd::ControlParameters()
+                                                .setName(prefix)
+                                                .setFaceId(faceId)
+                                                .setOrigin(nfd::ROUTE_ORIGIN_AUTOCONF)
+                                                .setCost(100)
+                                                .setExpirationPeriod(time::milliseconds::max()),
+                                              bind(&Base::onPrefixRegistrationSuccess, this, _1),
+                                              bind(&Base::onPrefixRegistrationError, this, _1, _2));
+}
+
+void
+Base::onPrefixRegistrationSuccess(const nfd::ControlParameters& commandSuccessResult)
+{
+  std::cerr << "Successful in name registration: " << commandSuccessResult << std::endl;
+}
+
+void
+Base::onPrefixRegistrationError(uint32_t code, const std::string& error)
+{
+  std::ostringstream os;
+  os << "Failed in name registration, " << error << " (code: " << code << ")";
+  throw Error(os.str());
+}
+
+
+} // namespace autoconfig
+} // namespace tools
+} // namespace ndn
diff --git a/tools/ndn-autoconfig/base.hpp b/tools/ndn-autoconfig/base.hpp
new file mode 100644
index 0000000..bf195c6
--- /dev/null
+++ b/tools/ndn-autoconfig/base.hpp
@@ -0,0 +1,120 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  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 NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_TOOLS_NDN_AUTOCONFIG_BASE_HPP
+#define NFD_TOOLS_NDN_AUTOCONFIG_BASE_HPP
+
+#include "common.hpp"
+
+#include <boost/noncopyable.hpp>
+
+#include <ndn-cxx/face.hpp>
+#include <ndn-cxx/security/key-chain.hpp>
+#include <ndn-cxx/management/nfd-controller.hpp>
+#include <ndn-cxx/management/nfd-face-status.hpp>
+#include <ndn-cxx/encoding/buffer-stream.hpp>
+#include <ndn-cxx/util/face-uri.hpp>
+
+namespace ndn {
+namespace tools {
+namespace autoconfig {
+
+/**
+ * @brief Base class for discovery stages
+ */
+class Base : boost::noncopyable
+{
+public:
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+  /**
+   * @brief Callback to be called when the stage fails
+   */
+  typedef std::function<void(const std::string&)> NextStageCallback;
+
+  /**
+   * @brief Start the stage
+   */
+  virtual void
+  start() = 0;
+
+protected:
+  /**
+   * @brief Initialize variables and create nfd::Controller instance
+   * @param face Face to be used for all operations (e.g., will send registration commands)
+   * @param keyChain KeyChain object
+   * @param nextStageOnFailure Callback to be called after the stage failed
+   */
+  Base(Face& face, KeyChain& keyChain, const NextStageCallback& nextStageOnFailure);
+
+  /**
+   * @brief Attempt to connect to local hub using the \p uri FaceUri
+   * @throw Base::Error when failed to establish the tunnel
+   */
+  void
+  connectToHub(const std::string& uri);
+
+private:
+  void
+  onCanonizeSuccess(const util::FaceUri& canonicalUri);
+
+  void
+  onCanonizeFailure(const std::string& reason);
+
+  void
+  onHubConnectSuccess(const nfd::ControlParameters& resp);
+
+  void
+  onHubConnectError(uint32_t code, const std::string& error);
+
+  void
+  registerPrefix(const Name& prefix, uint64_t faceId);
+
+  void
+  onPrefixRegistrationSuccess(const nfd::ControlParameters& commandSuccessResult);
+
+  void
+  onPrefixRegistrationError(uint32_t code, const std::string& error);
+
+protected:
+  Face& m_face;
+  KeyChain& m_keyChain;
+  nfd::Controller m_controller;
+  NextStageCallback m_nextStageOnFailure;
+};
+
+} // namespace autoconfig
+} // namespace tools
+} // namespace ndn
+
+#endif // NFD_TOOLS_NDN_AUTOCONFIG_BASE_HPP
diff --git a/tools/ndn-autoconfig/guess-from-identity-name.cpp b/tools/ndn-autoconfig/guess-from-identity-name.cpp
new file mode 100644
index 0000000..5a6df3e
--- /dev/null
+++ b/tools/ndn-autoconfig/guess-from-identity-name.cpp
@@ -0,0 +1,63 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  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 NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "guess-from-identity-name.hpp"
+
+namespace ndn {
+namespace tools {
+namespace autoconfig {
+
+GuessFromIdentityName::GuessFromIdentityName(Face& face, KeyChain& keyChain,
+                                             const NextStageCallback& nextStageOnFailure)
+  : BaseDns(face, keyChain, nextStageOnFailure)
+{
+}
+
+void
+GuessFromIdentityName::start()
+{
+  std::cerr << "Trying to find home router based on the default identity name..." << std::endl;
+
+  Name identity = m_keyChain.getDefaultIdentity();
+
+  std::ostringstream serverName;
+  for (auto i = identity.rbegin(); i != identity.rend(); ++i) {
+    serverName << i->toUri() << ".";
+  }
+  serverName << "_homehub._autoconf.named-data.net";
+
+  try {
+    std::string hubUri = BaseDns::querySrvRr(serverName.str());
+    this->connectToHub(hubUri);
+  }
+  catch (const BaseDns::Error& e) {
+    m_nextStageOnFailure(std::string("Failed to find a home router based on the default identity "
+                                     "name (") + e.what() + ")");
+  }
+}
+
+} // namespace autoconfig
+} // namespace tools
+} // namespace ndn
diff --git a/tools/ndn-autoconfig/guess-from-identity-name.hpp b/tools/ndn-autoconfig/guess-from-identity-name.hpp
new file mode 100644
index 0000000..3e0008f
--- /dev/null
+++ b/tools/ndn-autoconfig/guess-from-identity-name.hpp
@@ -0,0 +1,74 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  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 NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_TOOLS_NDN_AUTOCONFIG_GUESS_FROM_IDENTITY_NAME_HPP
+#define NFD_TOOLS_NDN_AUTOCONFIG_GUESS_FROM_IDENTITY_NAME_HPP
+
+#include "base-dns.hpp"
+
+namespace ndn {
+namespace tools {
+namespace autoconfig {
+
+/**
+ * @brief Guessing home router based on the default identity name
+ *
+ * This stage assumes that user has configured default certificate using
+ * http://ndncert.named-data.net/
+ *
+ * - Request
+ *
+ *     The end host loads the default user identity (eg. /ndn/edu/ucla/cs/afanasev), and
+ *     converts it to DNS format.
+ *
+ *     The end host sends a DNS query for an SRV record of name _ndn._udp. + user identity in
+ *     DNS format + _homehub._auto-conf.named-data.net. For example:
+ *
+ *         _ndn._udp.afanasev.cs.ucla.edu.ndn._homehub._autoconf.named-data.net
+ *
+ * - Response
+ *
+ *     The DNS server should answer with an SRV record that contains the hostname and UDP port
+ *     number of the home NDN router of this user's site.
+ */
+class GuessFromIdentityName : public BaseDns
+{
+public:
+  /**
+   * @brief Create stage to guess home router based on the default identity name
+   * @sa Base::Base
+   */
+  GuessFromIdentityName(Face& face, KeyChain& keyChain,
+                        const NextStageCallback& nextStageOnFailure);
+
+  virtual void
+  start() DECL_OVERRIDE;
+};
+
+} // namespace autoconfig
+} // namespace tools
+} // namespace ndn
+
+#endif // NFD_TOOLS_NDN_AUTOCONFIG_GUESSING_FROM_IDENTITY_NAME_HPP
diff --git a/tools/ndn-autoconfig/guess-from-search-domains.cpp b/tools/ndn-autoconfig/guess-from-search-domains.cpp
new file mode 100644
index 0000000..2f452e7
--- /dev/null
+++ b/tools/ndn-autoconfig/guess-from-search-domains.cpp
@@ -0,0 +1,53 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  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 NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "guess-from-search-domains.hpp"
+
+namespace ndn {
+namespace tools {
+namespace autoconfig {
+
+GuessFromSearchDomains::GuessFromSearchDomains(Face& face, KeyChain& keyChain,
+                                               const NextStageCallback& nextStageOnFailure)
+  : BaseDns(face, keyChain, nextStageOnFailure)
+{
+}
+
+void
+GuessFromSearchDomains::start()
+{
+  try {
+    std::string hubUri = BaseDns::querySrvRrSearch();
+    this->connectToHub(hubUri);
+  }
+  catch (const BaseDns::Error& e) {
+    m_nextStageOnFailure(std::string("Failed to find NDN router using default suffix DNS query (") +
+                         e.what() + ")");
+  }
+}
+
+} // namespace autoconfig
+} // namespace tools
+} // namespace ndn
diff --git a/tools/ndn-autoconfig/guess-from-search-domains.hpp b/tools/ndn-autoconfig/guess-from-search-domains.hpp
new file mode 100644
index 0000000..e2eaa5a
--- /dev/null
+++ b/tools/ndn-autoconfig/guess-from-search-domains.hpp
@@ -0,0 +1,67 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  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 NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_TOOLS_NDN_AUTOCONFIG_GUESS_FROM_SEARCH_DOMAINS_HPP
+#define NFD_TOOLS_NDN_AUTOCONFIG_GUESS_FROM_SEARCH_DOMAINS_HPP
+
+#include "base-dns.hpp"
+
+namespace ndn {
+namespace tools {
+namespace autoconfig {
+
+/**
+ * @brief Guessing home router based on DNS query with default suffix
+ *
+ * - Request
+ *
+ *     The end host sends a DNS query that is equivalent to this command:
+ *
+ *         dig +search +short +cmd +tries=2 +ndots=10 _ndn._udp srv
+ *
+ * - Response
+ *
+ *     The DNS server should answer with an SRV record that contains the hostname and UDP port
+ *     number of the NDN router.
+ */
+class GuessFromSearchDomains : public BaseDns
+{
+public:
+  /**
+   * @brief Create stage to guess home router based on DNS query with default suffix
+   * @sa Base::Base
+   */
+  GuessFromSearchDomains(Face& face, KeyChain& keyChain,
+                         const NextStageCallback& nextStageOnFailure);
+
+  virtual void
+  start() DECL_OVERRIDE;
+};
+
+} // namespace autoconfig
+} // namespace tools
+} // namespace ndn
+
+#endif // NFD_TOOLS_NDN_AUTOCONFIG_GUESSING_FROM_SEARCH_DOMAINS_HPP
diff --git a/tools/ndn-autoconfig/main.cpp b/tools/ndn-autoconfig/main.cpp
new file mode 100644
index 0000000..d604c9d
--- /dev/null
+++ b/tools/ndn-autoconfig/main.cpp
@@ -0,0 +1,126 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  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 NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "version.hpp"
+
+#include "multicast-discovery.hpp"
+#include "guess-from-search-domains.hpp"
+#include "guess-from-identity-name.hpp"
+
+#include <boost/noncopyable.hpp>
+
+namespace ndn {
+namespace tools {
+
+class NdnAutoconfig : boost::noncopyable
+{
+public:
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+  NdnAutoconfig()
+    : m_stage1(m_face, m_keyChain,
+               [&] (const std::string& errorMessage) {
+                 std::cerr << "Stage 1 failed: " << errorMessage << std::endl;
+                 m_stage2.start();
+               })
+    , m_stage2(m_face, m_keyChain,
+               [&] (const std::string& errorMessage) {
+                 std::cerr << "Stage 2 failed: " << errorMessage << std::endl;
+                 m_stage3.start();
+               })
+    , m_stage3(m_face, m_keyChain,
+               [&] (const std::string& errorMessage) {
+                 std::cerr << "Stage 3 failed: " << errorMessage << std::endl;
+                 throw Error("No more stages, automatic discovery failed");
+               })
+  {
+    m_stage1.start();
+  }
+
+  void
+  run()
+  {
+    m_face.processEvents();
+  }
+
+  static void
+  usage(const char* programName)
+  {
+    std::cout << "Usage:\n"
+              << "  " << programName  << " [options]\n"
+              << "\n"
+              << "Options:\n"
+              << "  [-h]  - print usage and exit\n"
+              << "  [-V]  - print version number and exit\n"
+              << std::endl;
+  }
+
+private:
+  Face m_face;
+  KeyChain m_keyChain;
+
+  autoconfig::MulticastDiscovery m_stage1;
+  autoconfig::GuessFromSearchDomains m_stage2;
+  autoconfig::GuessFromIdentityName m_stage3;
+};
+
+} // namespace tools
+} // namespace ndn
+
+int
+main(int argc, char** argv)
+{
+  int opt;
+  const char* programName = argv[0];
+
+  while ((opt = getopt(argc, argv, "hV")) != -1) {
+    switch (opt) {
+    case 'h':
+      ndn::tools::NdnAutoconfig::usage(programName);
+      return 0;
+    case 'V':
+      std::cout << NFD_VERSION_BUILD_STRING << std::endl;
+      return 0;
+    }
+  }
+
+  try {
+    ndn::tools::NdnAutoconfig autoConfigInstance;
+    autoConfigInstance.run();
+  }
+  catch (const std::exception& error) {
+    std::cerr << "ERROR: " << error.what() << std::endl;
+    return 1;
+  }
+  return 0;
+}
diff --git a/tools/ndn-autoconfig/multicast-discovery.cpp b/tools/ndn-autoconfig/multicast-discovery.cpp
new file mode 100644
index 0000000..59db21f
--- /dev/null
+++ b/tools/ndn-autoconfig/multicast-discovery.cpp
@@ -0,0 +1,194 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  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 NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "multicast-discovery.hpp"
+
+#include <ndn-cxx/util/segment-fetcher.hpp>
+
+namespace ndn {
+namespace tools {
+namespace autoconfig {
+
+static const Name LOCALHOP_HUB_DISCOVERY_PREFIX = "/localhop/ndn-autoconf/hub";
+
+MulticastDiscovery::MulticastDiscovery(Face& face, KeyChain& keyChain,
+                                       const NextStageCallback& nextStageOnFailure)
+  : Base(face, keyChain, nextStageOnFailure)
+  , nRequestedRegs(0)
+  , nFinishedRegs(0)
+{
+}
+
+void
+MulticastDiscovery::start()
+{
+  std::cerr << "Trying multicast discovery..." << std::endl;
+
+  util::SegmentFetcher::fetch(m_face, Interest("/localhost/nfd/faces/list"),
+                              ndn::util::DontVerifySegment(),
+                              [this] (const ConstBufferPtr& data) {
+                                registerHubDiscoveryPrefix(data);
+                              },
+                              [this] (uint32_t code, const std::string& msg) {
+                                m_nextStageOnFailure(msg);
+                              });
+}
+
+void
+MulticastDiscovery::registerHubDiscoveryPrefix(const ConstBufferPtr& buffer)
+{
+  std::vector<uint64_t> multicastFaces;
+
+  size_t offset = 0;
+  while (offset < buffer->size()) {
+    Block block;
+    bool ok = Block::fromBuffer(buffer, offset, block);
+    if (!ok)
+      {
+        std::cerr << "ERROR: cannot decode FaceStatus TLV" << std::endl;
+        break;
+      }
+
+    offset += block.size();
+
+    nfd::FaceStatus faceStatus(block);
+
+    ndn::util::FaceUri uri(faceStatus.getRemoteUri());
+    if (uri.getScheme() == "udp4") {
+      namespace ip = boost::asio::ip;
+      boost::system::error_code ec;
+      ip::address address = ip::address::from_string(uri.getHost(), ec);
+
+      if (!ec && address.is_multicast()) {
+        multicastFaces.push_back(faceStatus.getFaceId());
+      }
+      else
+        continue;
+    }
+  }
+
+  if (multicastFaces.empty()) {
+    m_nextStageOnFailure("No multicast faces available, skipping multicast discovery stage");
+  }
+  else {
+    nfd::ControlParameters parameters;
+    parameters
+      .setName(LOCALHOP_HUB_DISCOVERY_PREFIX)
+      .setCost(1)
+      .setExpirationPeriod(time::seconds(30));
+
+    nRequestedRegs = multicastFaces.size();
+    nFinishedRegs = 0;
+
+    for (const auto& face : multicastFaces) {
+      parameters.setFaceId(face);
+      m_controller.start<nfd::RibRegisterCommand>(parameters,
+                                                  bind(&MulticastDiscovery::onRegisterSuccess,
+                                                       this),
+                                                  bind(&MulticastDiscovery::onRegisterFailure,
+                                                       this, _1, _2));
+    }
+  }
+}
+
+void
+MulticastDiscovery::onRegisterSuccess()
+{
+  ++nFinishedRegs;
+
+  if (nRequestedRegs == nFinishedRegs) {
+    MulticastDiscovery::setStrategy();
+  }
+}
+
+void
+MulticastDiscovery::onRegisterFailure(uint32_t code, const std::string& error)
+{
+  std::cerr << "ERROR: " << error << " (code: " << code << ")" << std::endl;
+  --nRequestedRegs;
+
+  if (nRequestedRegs == nFinishedRegs) {
+    if (nRequestedRegs > 0) {
+      MulticastDiscovery::setStrategy();
+    } else {
+      m_nextStageOnFailure("Failed to register " + LOCALHOP_HUB_DISCOVERY_PREFIX.toUri() +
+                           " for all multicast faces, skipping multicast discovery stage");
+    }
+  }
+}
+
+void
+MulticastDiscovery::setStrategy()
+{
+  nfd::ControlParameters parameters;
+  parameters
+    .setName(LOCALHOP_HUB_DISCOVERY_PREFIX)
+    .setStrategy("/localhost/nfd/strategy/broadcast");
+
+  m_controller.start<nfd::StrategyChoiceSetCommand>(parameters,
+                                                    bind(&MulticastDiscovery::requestHubData, this),
+                                                    bind(&MulticastDiscovery::onSetStrategyFailure,
+                                                         this, _2));
+}
+
+void
+MulticastDiscovery::onSetStrategyFailure(const std::string& error)
+{
+  m_nextStageOnFailure("Failed to set broadcast strategy for " +
+                       LOCALHOP_HUB_DISCOVERY_PREFIX.toUri() + " namespace (" + error + "). "
+                       "Skipping multicast discovery stage");
+}
+
+void
+MulticastDiscovery::requestHubData()
+{
+  Interest interest(LOCALHOP_HUB_DISCOVERY_PREFIX);
+  interest.setInterestLifetime(time::milliseconds(4000)); // 4 seconds
+  interest.setMustBeFresh(true);
+
+  m_face.expressInterest(interest,
+                         bind(&MulticastDiscovery::onSuccess, this, _2),
+                         bind(m_nextStageOnFailure, "Timeout"));
+}
+
+void
+MulticastDiscovery::onSuccess(Data& data)
+{
+  const Block& content = data.getContent();
+  content.parse();
+
+  // Get Uri
+  Block::element_const_iterator blockValue = content.find(tlv::nfd::Uri);
+  if (blockValue == content.elements_end()) {
+    m_nextStageOnFailure("Incorrect reply to multicast discovery stage");
+    return;
+  }
+  std::string hubUri(reinterpret_cast<const char*>(blockValue->value()), blockValue->value_size());
+  this->connectToHub(hubUri);
+}
+
+} // namespace autoconfig
+} // namespace tools
+} // namespace ndn
diff --git a/tools/ndn-autoconfig/multicast-discovery.hpp b/tools/ndn-autoconfig/multicast-discovery.hpp
new file mode 100644
index 0000000..72717fc
--- /dev/null
+++ b/tools/ndn-autoconfig/multicast-discovery.hpp
@@ -0,0 +1,94 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  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 NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_TOOLS_NDN_AUTOCONFIG_MULTICAST_DISCOVERY_HPP
+#define NFD_TOOLS_NDN_AUTOCONFIG_MULTICAST_DISCOVERY_HPP
+
+#include "base.hpp"
+
+namespace ndn {
+namespace tools {
+namespace autoconfig {
+
+/**
+ * @brief Multicast discovery stage
+ *
+ * - Request
+ *
+ *     The end host sends an Interest over a multicast face.
+ *
+ *     Interest Name is /localhop/ndn-autoconf/hub.
+ *
+ * - Response
+ *
+ *     A producer app on the HUB answer this Interest with a Data packet that contains a
+ *     TLV-encoded Uri block.  The value of this block is the URI for the HUB, preferably a
+ *     UDP tunnel.
+ */
+class MulticastDiscovery : public Base
+{
+public:
+  /**
+   * @brief Create multicast discovery stage
+   * @sa Base::Base
+   */
+  MulticastDiscovery(Face& face, KeyChain& keyChain, const NextStageCallback& nextStageOnFailure);
+
+  virtual void
+  start() DECL_OVERRIDE;
+
+private:
+  void
+  registerHubDiscoveryPrefix(const ConstBufferPtr& buffer);
+
+  void
+  onRegisterSuccess();
+
+  void
+  onRegisterFailure(uint32_t code, const std::string& error);
+
+  void
+  setStrategy();
+
+  void
+  onSetStrategyFailure(const std::string& error);
+
+  // Start to look for a hub (NDN hub discovery first stage)
+  void
+  requestHubData();
+
+  void
+  onSuccess(Data& data);
+
+private:
+  size_t nRequestedRegs;
+  size_t nFinishedRegs;
+};
+
+} // namespace autoconfig
+} // namespace tools
+} // namespace ndn
+
+#endif // NFD_TOOLS_NDN_AUTOCONFIG_MULTICAST_DISCOVERY_HPP
