diff --git a/src/publisher/dataset-interest-handler.cpp b/src/publisher/dataset-interest-handler.cpp
new file mode 100644
index 0000000..efd76f8
--- /dev/null
+++ b/src/publisher/dataset-interest-handler.cpp
@@ -0,0 +1,261 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2018,  The University of Memphis,
+ *                           Regents of the University of California,
+ *                           Arizona Board of Regents.
+ *
+ * This file is part of NLSR (Named-data Link State Routing).
+ * See AUTHORS.md for complete list of NLSR authors and contributors.
+ *
+ * NLSR 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.
+ *
+ * NLSR 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
+ * NLSR, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "dataset-interest-handler.hpp"
+#include "nlsr.hpp"
+#include "tlv/lsdb-status.hpp"
+#include "logger.hpp"
+
+#include <ndn-cxx/mgmt/nfd/control-response.hpp>
+#include <ndn-cxx/util/regex.hpp>
+
+namespace nlsr {
+
+INIT_LOGGER("DatasetInterestHandler");
+
+const ndn::PartialName ADJACENCIES_DATASET = ndn::PartialName("lsdb/adjacencies");
+const ndn::PartialName COORDINATES_DATASET = ndn::PartialName("lsdb/coordinates");
+const ndn::PartialName NAMES_DATASET = ndn::PartialName("lsdb/names");
+const ndn::PartialName RT_DATASET = ndn::PartialName("routing-table");
+
+DatasetInterestHandler::DatasetInterestHandler(const Lsdb& lsdb,
+                                               const RoutingTable& rt,
+                                               ndn::mgmt::Dispatcher& dispatcher,
+                                               const ndn::Face& face,
+                                               const ndn::KeyChain& keyChain)
+  : m_lsdb(lsdb)
+  , m_dispatcher(dispatcher)
+  , m_routingTableEntries(rt.getRoutingTableEntry())
+  , m_dryRoutingTableEntries(rt.getDryRoutingTableEntry())
+{
+  setDispatcher(m_dispatcher);
+}
+
+void
+DatasetInterestHandler::setDispatcher(ndn::mgmt::Dispatcher& dispatcher)
+{
+  dispatcher.addStatusDataset(ADJACENCIES_DATASET,
+    ndn::mgmt::makeAcceptAllAuthorization(),
+    std::bind(&DatasetInterestHandler::publishAdjStatus, this, _1, _2, _3));
+  dispatcher.addStatusDataset(COORDINATES_DATASET,
+    ndn::mgmt::makeAcceptAllAuthorization(),
+    std::bind(&DatasetInterestHandler::publishCoordinateStatus, this, _1, _2, _3));
+  dispatcher.addStatusDataset(NAMES_DATASET,
+    ndn::mgmt::makeAcceptAllAuthorization(),
+    std::bind(&DatasetInterestHandler::publishNameStatus, this, _1, _2, _3));
+  dispatcher.addStatusDataset(RT_DATASET,
+    ndn::mgmt::makeAcceptAllAuthorization(),
+    std::bind(&DatasetInterestHandler::publishRtStatus, this, _1, _2, _3));
+}
+
+void
+DatasetInterestHandler::publishAdjStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
+                                         ndn::mgmt::StatusDatasetContext& context)
+{
+  NLSR_LOG_DEBUG("Received interest:  " << interest);
+
+  auto lsaRange = std::make_pair<std::list<AdjLsa>::const_iterator,
+                                 std::list<AdjLsa>::const_iterator>(
+    m_lsdb.getAdjLsdb().cbegin(), m_lsdb.getAdjLsdb().cend());
+  for (auto lsa = lsaRange.first; lsa != lsaRange.second; lsa++) {
+    tlv::AdjacencyLsa tlvLsa;
+    std::shared_ptr<tlv::LsaInfo> tlvLsaInfo = tlv::makeLsaInfo(*lsa);
+    tlvLsa.setLsaInfo(*tlvLsaInfo);
+
+    for (const Adjacent& adj : lsa->getAdl().getAdjList()) {
+      tlv::Adjacency tlvAdj;
+      tlvAdj.setName(adj.getName());
+      tlvAdj.setUri(adj.getFaceUri().toString());
+      tlvAdj.setCost(adj.getLinkCost());
+      tlvLsa.addAdjacency(tlvAdj);
+    }
+    const ndn::Block& wire = tlvLsa.wireEncode();
+    context.append(wire);
+  }
+  context.end();
+}
+
+void
+DatasetInterestHandler::publishCoordinateStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
+                                                ndn::mgmt::StatusDatasetContext& context)
+{
+  auto lsaRange = std::make_pair<std::list<CoordinateLsa>::const_iterator,
+                                 std::list<CoordinateLsa>::const_iterator>(
+    m_lsdb.getCoordinateLsdb().cbegin(), m_lsdb.getCoordinateLsdb().cend());
+
+  NLSR_LOG_DEBUG("Received interest:  " << interest);
+  for (auto lsa = lsaRange.first; lsa != lsaRange.second; lsa++) {
+    tlv::CoordinateLsa tlvLsa;
+    std::shared_ptr<tlv::LsaInfo> tlvLsaInfo = tlv::makeLsaInfo(*lsa);
+    tlvLsa.setLsaInfo(*tlvLsaInfo);
+
+    tlvLsa.setHyperbolicRadius(lsa->getCorRadius());
+    tlvLsa.setHyperbolicAngle(lsa->getCorTheta());
+
+    const ndn::Block& wire = tlvLsa.wireEncode();
+    context.append(wire);
+  }
+  context.end();
+}
+
+void
+DatasetInterestHandler::publishNameStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
+                                          ndn::mgmt::StatusDatasetContext& context)
+{
+  auto lsaRange = std::make_pair<std::list<NameLsa>::const_iterator, std::list<NameLsa>::const_iterator>(
+    m_lsdb.getNameLsdb().cbegin(), m_lsdb.getNameLsdb().cend());
+  NLSR_LOG_DEBUG("Received interest:  " << interest);
+  for (auto lsa = lsaRange.first; lsa != lsaRange.second; lsa++) {
+    tlv::NameLsa tlvLsa;
+
+    std::shared_ptr<tlv::LsaInfo> tlvLsaInfo = tlv::makeLsaInfo(*lsa);
+    tlvLsa.setLsaInfo(*tlvLsaInfo);
+
+    for (const ndn::Name& name : lsa->getNpl().getNames()) {
+      tlvLsa.addName(name);
+    }
+
+    const ndn::Block& wire = tlvLsa.wireEncode();
+    context.append(wire);
+  }
+  context.end();
+}
+
+void
+DatasetInterestHandler::publishRtStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
+                                        ndn::mgmt::StatusDatasetContext& context)
+{
+  NLSR_LOG_DEBUG("Received interest for routing table:  " << interest);
+  tlv::RoutingTable tlvRoutingTable;
+
+  for (const auto& rte : m_routingTableEntries) {
+    std::shared_ptr<tlv::Destination> tlvDes = tlv::makeDes(rte);
+    tlvRoutingTable.setDestination(*tlvDes);
+
+    for (const auto& nh : rte.getNexthopList().getNextHops()) {
+      tlv::NextHop tlvNexthop;
+      tlvNexthop.setUri(nh.getConnectingFaceUri());
+      tlvNexthop.setCost(nh.getRouteCost());
+      tlvRoutingTable.addNexthops(tlvNexthop);
+    }
+
+    const ndn::Block& wire = tlvRoutingTable.wireEncode();
+    context.append(wire);
+  }
+  if (!m_dryRoutingTableEntries.empty()) {
+    for (const auto& dry_rte : m_dryRoutingTableEntries ) {
+        std::shared_ptr<tlv::Destination> tlvDes = tlv::makeDes(dry_rte);
+        tlvRoutingTable.setDestination(*tlvDes);
+
+        for (const auto& nh : dry_rte.getNexthopList().getNextHops()) {
+          tlv::NextHop tlvNexthop;
+          tlvNexthop.setUri(nh.getConnectingFaceUri());
+          tlvNexthop.setCost(nh.getRouteCost());
+          tlvRoutingTable.addNexthops(tlvNexthop);
+        }
+        const ndn::Block& wire = tlvRoutingTable.wireEncode();
+        context.append(wire);
+      }
+  }
+
+  context.end();
+}
+
+template<> std::list<tlv::AdjacencyLsa>
+getTlvLsas<tlv::AdjacencyLsa>(const Lsdb& lsdb)
+{
+  std::list<tlv::AdjacencyLsa> lsas;
+
+  auto lsaRange = std::make_pair<std::list<AdjLsa>::const_iterator,
+                                 std::list<AdjLsa>::const_iterator>(
+    lsdb.getAdjLsdb().cbegin(), lsdb.getAdjLsdb().cend());
+  for (auto lsa = lsaRange.first; lsa != lsaRange.second; lsa++) {
+    tlv::AdjacencyLsa tlvLsa;
+
+    std::shared_ptr<tlv::LsaInfo> tlvLsaInfo = tlv::makeLsaInfo(*lsa);
+    tlvLsa.setLsaInfo(*tlvLsaInfo);
+
+    for (const Adjacent& adj : lsa->getAdl().getAdjList()) {
+      tlv::Adjacency tlvAdj;
+      tlvAdj.setName(adj.getName());
+      tlvAdj.setUri(adj.getFaceUri().toString());
+      tlvAdj.setCost(adj.getLinkCost());
+      tlvLsa.addAdjacency(tlvAdj);
+    }
+
+    lsas.push_back(tlvLsa);
+  }
+
+  return lsas;
+
+}
+
+template<> std::list<tlv::CoordinateLsa>
+getTlvLsas<tlv::CoordinateLsa>(const Lsdb& lsdb)
+{
+  std::list<tlv::CoordinateLsa> lsas;
+
+  auto lsaRange = std::make_pair<std::list<CoordinateLsa>::const_iterator,
+                                 std::list<CoordinateLsa>::const_iterator>(
+    lsdb.getCoordinateLsdb().cbegin(), lsdb.getCoordinateLsdb().cend());
+
+  for (auto lsa = lsaRange.first; lsa != lsaRange.second; lsa++) {
+    tlv::CoordinateLsa tlvLsa;
+
+    std::shared_ptr<tlv::LsaInfo> tlvLsaInfo = tlv::makeLsaInfo(*lsa);
+    tlvLsa.setLsaInfo(*tlvLsaInfo);
+
+    tlvLsa.setHyperbolicRadius(lsa->getCorRadius());
+    tlvLsa.setHyperbolicAngle(lsa->getCorTheta());
+
+    lsas.push_back(tlvLsa);
+  }
+
+  return lsas;
+
+}
+
+template<> std::list<tlv::NameLsa>
+getTlvLsas<tlv::NameLsa>(const Lsdb& lsdb)
+{
+  std::list<tlv::NameLsa> lsas;
+
+  auto lsaRange = std::make_pair<std::list<NameLsa>::const_iterator,
+                                 std::list<NameLsa>::const_iterator>(
+    lsdb.getNameLsdb().cbegin(), lsdb.getNameLsdb().cend());
+  for (auto lsa = lsaRange.first; lsa != lsaRange.second; lsa++) {
+    tlv::NameLsa tlvLsa;
+
+    std::shared_ptr<tlv::LsaInfo> tlvLsaInfo = tlv::makeLsaInfo(*lsa);
+    tlvLsa.setLsaInfo(*tlvLsaInfo);
+
+    for (const ndn::Name& name : lsa->getNpl().getNames()) {
+      tlvLsa.addName(name);
+    }
+
+    lsas.push_back(tlvLsa);
+  }
+
+  return lsas;
+
+}
+
+} // namespace nlsr
