diff --git a/src/lsdb.cpp b/src/lsdb.cpp
index 8c41c9f..1374906 100644
--- a/src/lsdb.cpp
+++ b/src/lsdb.cpp
@@ -32,6 +32,7 @@
 
 INIT_LOGGER("Lsdb");
 
+const ndn::Name::Component Lsdb::NAME_COMPONENT = ndn::Name::Component("lsdb");
 const ndn::time::seconds Lsdb::GRACE_PERIOD = ndn::time::seconds(10);
 const steady_clock::TimePoint Lsdb::DEFAULT_LSA_RETRIEVAL_DEADLINE = steady_clock::TimePoint::min();
 
@@ -248,6 +249,12 @@
   }
 }
 
+const std::list<NameLsa>&
+Lsdb::getNameLsdb()
+{
+  return m_nameLsdb;
+}
+
 // Cor LSA and LSDB related Functions start here
 
 static bool
@@ -420,6 +427,12 @@
   }
 }
 
+const std::list<CoordinateLsa>&
+Lsdb::getCoordinateLsdb()
+{
+  return m_corLsdb;
+}
+
 // Adj LSA and LSDB related function starts here
 
 static bool
@@ -625,7 +638,7 @@
   return true;
 }
 
-std::list<AdjLsa>&
+const std::list<AdjLsa>&
 Lsdb::getAdjLsdb()
 {
   return m_adjLsdb;
diff --git a/src/lsdb.hpp b/src/lsdb.hpp
index 34d7562..7ab54e5 100644
--- a/src/lsdb.hpp
+++ b/src/lsdb.hpp
@@ -73,6 +73,9 @@
   void
   writeNameLsdbLog();
 
+  const std::list<NameLsa>&
+  getNameLsdb();
+
   //function related to Cor LSDB
   bool
   buildAndInstallOwnCoordinateLsa();
@@ -92,6 +95,9 @@
   void
   writeCorLsdbLog();
 
+  const std::list<CoordinateLsa>&
+  getCoordinateLsdb();
+
   //function related to Adj LSDB
 
   void
@@ -105,13 +111,14 @@
 
   bool
   isAdjLsaNew(const ndn::Name& key, uint64_t seqNo);
+
   bool
   installAdjLsa(AdjLsa& alsa);
 
   AdjLsa*
   findAdjLsa(const ndn::Name& key);
 
-  std::list<AdjLsa>&
+  const std::list<AdjLsa>&
   getAdjLsdb();
 
   void
@@ -257,6 +264,9 @@
   void
   cancelScheduleLsaExpiringEvent(ndn::EventId eid);
 
+public:
+  static const ndn::Name::Component NAME_COMPONENT;
+
 private:
   Nlsr& m_nlsr;
   ndn::Scheduler& m_scheduler;
diff --git a/src/nlsr.cpp b/src/nlsr.cpp
index c77cbf8..5d40002 100644
--- a/src/nlsr.cpp
+++ b/src/nlsr.cpp
@@ -47,6 +47,13 @@
 void
 Nlsr::onRegistrationSuccess(const ndn::Name& name)
 {
+  if (name.equals(m_confParam.getRouterPrefix())) {
+    m_lsdbDatasetHandler = std::unique_ptr<LsdbDatasetInterestHandler>(
+      new LsdbDatasetInterestHandler(m_nlsrLsdb,
+                                     m_nlsrFace,
+                                     m_confParam.getRouterPrefix(),
+                                     m_keyChain));
+  }
 }
 
 void
diff --git a/src/nlsr.hpp b/src/nlsr.hpp
index 7e73ebc..1b7527d 100644
--- a/src/nlsr.hpp
+++ b/src/nlsr.hpp
@@ -44,6 +44,7 @@
 #include "communication/sync-logic-handler.hpp"
 #include "hello-protocol.hpp"
 #include "test-access-control.hpp"
+#include "publisher/lsdb-dataset-interest-handler.hpp"
 
 #include "validator.hpp"
 
@@ -367,6 +368,7 @@
   NamePrefixTable m_namePrefixTable;
   SyncLogicHandler m_syncLogicHandler;
   HelloProtocol m_helloProtocol;
+  std::unique_ptr<LsdbDatasetInterestHandler> m_lsdbDatasetHandler;
 
 private:
   ndn::shared_ptr<ndn::CertificateCacheTtl> m_certificateCache;
diff --git a/src/publisher/lsa-publisher.cpp b/src/publisher/lsa-publisher.cpp
new file mode 100644
index 0000000..31192fd
--- /dev/null
+++ b/src/publisher/lsa-publisher.cpp
@@ -0,0 +1,140 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  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 "lsa-publisher.hpp"
+
+#include "lsa.hpp"
+
+#include <ndn-cxx/face.hpp>
+
+namespace nlsr {
+
+const ndn::Name::Component AdjacencyLsaPublisher::DATASET_COMPONENT =
+  ndn::Name::Component("adjacencies");
+
+AdjacencyLsaPublisher::AdjacencyLsaPublisher(Lsdb& lsdb,
+                                             ndn::Face& face,
+                                             const ndn::Name& prefix,
+                                             ndn::KeyChain& keyChain)
+  : LsaPublisher(face, prefix, keyChain, DATASET_COMPONENT)
+  , m_adjacencyLsas(lsdb.getAdjLsdb())
+{
+}
+
+std::list<tlv::AdjacencyLsa>
+AdjacencyLsaPublisher::getTlvLsas()
+{
+  std::list<tlv::AdjacencyLsa> lsas;
+
+  for (AdjLsa lsa : m_adjacencyLsas) {
+    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.getConnectingFaceUri());
+      tlvAdj.setCost(adj.getLinkCost());
+      tlvLsa.addAdjacency(tlvAdj);
+    }
+
+    lsas.push_back(tlvLsa);
+  }
+
+  return lsas;
+}
+
+//////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
+
+const ndn::Name::Component CoordinateLsaPublisher::DATASET_COMPONENT =
+  ndn::Name::Component("coordinates");
+
+CoordinateLsaPublisher::CoordinateLsaPublisher(Lsdb& lsdb,
+                                               ndn::Face& face,
+                                               const ndn::Name& prefix,
+                                               ndn::KeyChain& keyChain)
+  : LsaPublisher(face, prefix, keyChain, DATASET_COMPONENT)
+  , m_coordinateLsas(lsdb.getCoordinateLsdb())
+{
+}
+
+std::list<tlv::CoordinateLsa>
+CoordinateLsaPublisher::getTlvLsas()
+{
+  std::list<tlv::CoordinateLsa> lsas;
+
+  for (const CoordinateLsa lsa : m_coordinateLsas) {
+    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;
+}
+
+//////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
+
+const ndn::Name::Component NameLsaPublisher::DATASET_COMPONENT =
+  ndn::Name::Component("names");
+
+NameLsaPublisher::NameLsaPublisher(Lsdb& lsdb,
+                                   ndn::Face& face,
+                                   const ndn::Name& prefix,
+                                   ndn::KeyChain& keyChain)
+  : LsaPublisher(face, prefix, keyChain, DATASET_COMPONENT)
+  , m_nameLsas(lsdb.getNameLsdb())
+{
+}
+
+std::list<tlv::NameLsa>
+NameLsaPublisher::getTlvLsas()
+{
+  std::list<tlv::NameLsa> lsas;
+
+  for (NameLsa lsa : m_nameLsas) {
+    tlv::NameLsa tlvLsa;
+
+    std::shared_ptr<tlv::LsaInfo> tlvLsaInfo = tlv::makeLsaInfo(lsa);
+    tlvLsa.setLsaInfo(*tlvLsaInfo);
+
+    for (const ndn::Name& name : lsa.getNpl().getNameList()) {
+      tlvLsa.addName(name);
+    }
+
+    lsas.push_back(tlvLsa);
+  }
+
+  return lsas;
+}
+
+} // namespace nlsr
diff --git a/src/publisher/lsa-publisher.hpp b/src/publisher/lsa-publisher.hpp
new file mode 100644
index 0000000..09aec8c
--- /dev/null
+++ b/src/publisher/lsa-publisher.hpp
@@ -0,0 +1,137 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  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/>.
+ **/
+
+#ifndef NLSR_PUBLISHER_LSA_PUBLISHER_HPP
+#define NLSR_PUBLISHER_LSA_PUBLISHER_HPP
+
+#include "lsdb.hpp"
+#include "segment-publisher.hpp"
+#include "tlv/adjacency-lsa.hpp"
+#include "tlv/coordinate-lsa.hpp"
+#include "tlv/name-lsa.hpp"
+
+#include <ndn-cxx/face.hpp>
+
+namespace nlsr {
+
+template <class TlvType>
+class LsaPublisher : public SegmentPublisher<ndn::Face>
+{
+public:
+  LsaPublisher(ndn::Face& face,
+                const ndn::Name& prefix,
+                ndn::KeyChain& keyChain,
+                const ndn::Name::Component& datasetComponent)
+  : SegmentPublisher<ndn::Face>(face, ndn::Name(prefix).append(datasetComponent), keyChain)
+  {
+  }
+
+  virtual
+  ~LsaPublisher()
+  {
+  }
+
+protected:
+  virtual size_t
+  generate(ndn::EncodingBuffer& outBuffer)
+  {
+    size_t totalLength = 0;
+
+    for (const TlvType& lsaTlv : getTlvLsas()) {
+      totalLength += lsaTlv.wireEncode(outBuffer);
+    }
+
+    return totalLength;
+  }
+
+  virtual std::list<TlvType>
+  getTlvLsas() = 0;
+};
+
+/**
+ * @brief Abstraction to publish adjacency lsa dataset
+ * \sa http://redmine.named-data.net/projects/nlsr/wiki/LSDB_DataSet
+ */
+class AdjacencyLsaPublisher : public LsaPublisher<tlv::AdjacencyLsa>
+{
+public:
+  AdjacencyLsaPublisher(Lsdb& lsdb,
+                        ndn::Face& face,
+                        const ndn::Name& prefix,
+                        ndn::KeyChain& keyChain);
+
+  std::list<tlv::AdjacencyLsa>
+  getTlvLsas();
+
+public:
+  static const ndn::Name::Component DATASET_COMPONENT;
+
+private:
+  const std::list<AdjLsa>& m_adjacencyLsas;
+};
+
+/**
+ * @brief Abstraction to publish coordinate lsa dataset
+ * \sa http://redmine.named-data.net/projects/nlsr/wiki/LSDB_DataSet
+ */
+class CoordinateLsaPublisher : public LsaPublisher<tlv::CoordinateLsa>
+{
+public:
+  CoordinateLsaPublisher(Lsdb& lsdb,
+                        ndn::Face& face,
+                        const ndn::Name& prefix,
+                        ndn::KeyChain& keyChain);
+
+  std::list<tlv::CoordinateLsa>
+  getTlvLsas();
+
+public:
+  static const ndn::Name::Component DATASET_COMPONENT;
+
+private:
+  const std::list<CoordinateLsa>& m_coordinateLsas;
+};
+
+/**
+ * @brief Abstraction to publish name lsa dataset
+ * \sa http://redmine.named-data.net/projects/nlsr/wiki/LSDB_DataSet
+ */
+class NameLsaPublisher : public LsaPublisher<tlv::NameLsa>
+{
+public:
+  NameLsaPublisher(Lsdb& lsdb,
+                   ndn::Face& face,
+                   const ndn::Name& prefix,
+                   ndn::KeyChain& keyChain);
+
+  std::list<tlv::NameLsa>
+  getTlvLsas();
+
+public:
+  static const ndn::Name::Component DATASET_COMPONENT;
+
+private:
+  const std::list<NameLsa>& m_nameLsas;
+};
+
+} // namespace nlsr
+
+#endif // NLSR_PUBLISHER_LSA_PUBLISHER_HPP
diff --git a/src/publisher/lsdb-dataset-interest-handler.cpp b/src/publisher/lsdb-dataset-interest-handler.cpp
new file mode 100644
index 0000000..5285d28
--- /dev/null
+++ b/src/publisher/lsdb-dataset-interest-handler.cpp
@@ -0,0 +1,103 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  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 "lsdb-dataset-interest-handler.hpp"
+
+#include "logger.hpp"
+
+#include <ndn-cxx/face.hpp>
+#include <ndn-cxx/management/nfd-control-response.hpp>
+#include <ndn-cxx/util/regex.hpp>
+
+namespace nlsr {
+
+INIT_LOGGER("LsdbDatasetInterestHandler");
+
+LsdbDatasetInterestHandler::LsdbDatasetInterestHandler(Lsdb& lsdb,
+                                                       ndn::Face& face,
+                                                       const ndn::Name& routerName,
+                                                       ndn::KeyChain& keyChain)
+  : COMMAND_PREFIX(ndn::Name(routerName).append(Lsdb::NAME_COMPONENT))
+  , m_face(face)
+  , m_keyChain(keyChain)
+  , m_adjacencyLsaPublisher(lsdb, face, COMMAND_PREFIX, keyChain)
+  , m_coordinateLsaPublisher(lsdb, face, COMMAND_PREFIX, keyChain)
+  , m_nameLsaPublisher(lsdb, face, COMMAND_PREFIX, keyChain)
+  , m_lsdbStatusPublisher(lsdb, face, COMMAND_PREFIX, keyChain,
+                          m_adjacencyLsaPublisher,
+                          m_coordinateLsaPublisher,
+                          m_nameLsaPublisher)
+
+{
+  _LOG_DEBUG("Setting interest filter for: " << COMMAND_PREFIX);
+  m_face.setInterestFilter(COMMAND_PREFIX,
+                           std::bind(&LsdbDatasetInterestHandler::onInterest, this, _2));
+}
+
+void
+LsdbDatasetInterestHandler::onInterest(const ndn::Interest& interest)
+{
+  // Does interest match command prefix with one additional component?
+  if (interest.getName().size() != COMMAND_PREFIX.size() + 1 ||
+      !COMMAND_PREFIX.isPrefixOf(interest.getName()))
+  {
+    _LOG_DEBUG("Received malformed interest: " << interest.getName());
+
+    sendErrorResponse(interest.getName(), 400, "Malformed command");
+    return;
+  }
+
+  ndn::Name::Component command = interest.getName().get(COMMAND_PREFIX.size());
+  _LOG_TRACE("Received interest with command: " << command);
+
+  if (command.equals(AdjacencyLsaPublisher::DATASET_COMPONENT)) {
+    m_adjacencyLsaPublisher.publish();
+  }
+  else if (command.equals(CoordinateLsaPublisher::DATASET_COMPONENT)) {
+    m_coordinateLsaPublisher.publish();
+  }
+  else if (command.equals(NameLsaPublisher::DATASET_COMPONENT)) {
+    m_nameLsaPublisher.publish();
+  }
+  else if (command.equals(LsdbStatusPublisher::DATASET_COMPONENT)) {
+    m_lsdbStatusPublisher.publish();
+  }
+  else {
+    _LOG_DEBUG("Unsupported command: " << command);
+    sendErrorResponse(interest.getName(), 501, "Unsupported command");
+  }
+}
+
+void
+LsdbDatasetInterestHandler::sendErrorResponse(const ndn::Name& name,
+                                              uint32_t code,
+                                              const std::string& error)
+{
+  ndn::nfd::ControlResponse response(code, error);
+
+  std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>(name);
+  data->setContent(response.wireEncode());
+
+  m_keyChain.sign(*data);
+  m_face.put(*data);
+}
+
+} // namespace nlsr
diff --git a/src/publisher/lsdb-dataset-interest-handler.hpp b/src/publisher/lsdb-dataset-interest-handler.hpp
new file mode 100644
index 0000000..8f43c87
--- /dev/null
+++ b/src/publisher/lsdb-dataset-interest-handler.hpp
@@ -0,0 +1,74 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  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/>.
+ **/
+
+#ifndef NLSR_PUBLISHER_LSDB_DATASET_INTEREST_HANDLER_HPP
+#define NLSR_PUBLISHER_LSDB_DATASET_INTEREST_HANDLER_HPP
+
+#include "lsa-publisher.hpp"
+#include "lsdb-status-publisher.hpp"
+
+#include <ndn-cxx/face.hpp>
+
+namespace nlsr {
+
+/**
+ * @brief Abstraction to publish all lsa dataset
+ * \sa http://redmine.named-data.net/projects/nlsr/wiki/LSDB_DataSet
+ */
+class LsdbDatasetInterestHandler
+{
+public:
+  class Error : std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+  LsdbDatasetInterestHandler(Lsdb& lsdb,
+                             ndn::Face& face,
+                             const ndn::Name& routerName,
+                             ndn::KeyChain& keyChain);
+
+  void
+  onInterest(const ndn::Interest& interest);
+
+  void
+  sendErrorResponse(const ndn::Name& name, uint32_t code, const std::string& error);
+
+private:
+  const ndn::Name COMMAND_PREFIX;
+
+  ndn::Face& m_face;
+  ndn::KeyChain& m_keyChain;
+
+  AdjacencyLsaPublisher m_adjacencyLsaPublisher;
+  CoordinateLsaPublisher m_coordinateLsaPublisher;
+  NameLsaPublisher m_nameLsaPublisher;
+  LsdbStatusPublisher m_lsdbStatusPublisher;
+};
+
+} // namespace nlsr
+
+#endif // NLSR_PUBLISHER_LSDB_DATASET_INTEREST_HANDLER_HPP
diff --git a/src/publisher/lsdb-status-publisher.cpp b/src/publisher/lsdb-status-publisher.cpp
new file mode 100644
index 0000000..6905df6
--- /dev/null
+++ b/src/publisher/lsdb-status-publisher.cpp
@@ -0,0 +1,70 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  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 "lsdb-status-publisher.hpp"
+
+#include "lsa.hpp"
+#include "tlv/lsdb-status.hpp"
+
+#include <ndn-cxx/face.hpp>
+
+namespace nlsr {
+
+const ndn::Name::Component LsdbStatusPublisher::DATASET_COMPONENT = ndn::Name::Component("list");
+
+LsdbStatusPublisher::LsdbStatusPublisher(Lsdb& lsdb,
+                                         ndn::Face& face,
+                                         const ndn::Name& prefix,
+                                         ndn::KeyChain& keyChain,
+                                         AdjacencyLsaPublisher& adjacencyLsaPublisher,
+                                         CoordinateLsaPublisher& coordinateLsaPublisher,
+                                         NameLsaPublisher& nameLsaPublisher)
+  : SegmentPublisher<ndn::Face>(face, ndn::Name(prefix).append(DATASET_COMPONENT), keyChain)
+  , m_adjacencyLsaPublisher(adjacencyLsaPublisher)
+  , m_coordinateLsaPublisher(coordinateLsaPublisher)
+  , m_nameLsaPublisher(nameLsaPublisher)
+{
+}
+
+size_t
+LsdbStatusPublisher::generate(ndn::EncodingBuffer& outBuffer)
+{
+  size_t totalLength = 0;
+
+  tlv::LsdbStatus lsdbStatus;
+  for (const tlv::AdjacencyLsa& tlvLsa : m_adjacencyLsaPublisher.getTlvLsas()) {
+    lsdbStatus.addAdjacencyLsa(tlvLsa);
+  }
+
+  for (const tlv::CoordinateLsa& tlvLsa : m_coordinateLsaPublisher.getTlvLsas()) {
+    lsdbStatus.addCoordinateLsa(tlvLsa);
+  }
+
+  for (const tlv::NameLsa& tlvLsa : m_nameLsaPublisher.getTlvLsas()) {
+    lsdbStatus.addNameLsa(tlvLsa);
+  }
+
+  totalLength += lsdbStatus.wireEncode(outBuffer);
+
+  return totalLength;
+}
+
+} // namespace nlsr
diff --git a/src/publisher/lsdb-status-publisher.hpp b/src/publisher/lsdb-status-publisher.hpp
new file mode 100644
index 0000000..b8145a8
--- /dev/null
+++ b/src/publisher/lsdb-status-publisher.hpp
@@ -0,0 +1,63 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  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/>.
+ **/
+
+#ifndef NLSR_PUBLISHER_LSDB_STATUS_PUBLISHER_HPP
+#define NLSR_PUBLISHER_LSDB_STATUS_PUBLISHER_HPP
+
+#include "lsa-publisher.hpp"
+#include "lsdb.hpp"
+#include "segment-publisher.hpp"
+
+#include <ndn-cxx/face.hpp>
+
+namespace nlsr {
+
+/**
+ * @brief Abstraction to publish lsdb status dataset
+ * \sa http://redmine.named-data.net/projects/nlsr/wiki/LSDB_DataSet
+ */
+class LsdbStatusPublisher : public SegmentPublisher<ndn::Face>
+{
+public:
+  LsdbStatusPublisher(Lsdb& lsdb,
+                      ndn::Face& face,
+                      const ndn::Name& prefix,
+                      ndn::KeyChain& keyChain,
+                      AdjacencyLsaPublisher& adjacencyLsaPublisher,
+                      CoordinateLsaPublisher& coordinateLsaPublisher,
+                      NameLsaPublisher& nameLsaPublisher);
+
+protected:
+  virtual size_t
+  generate(ndn::EncodingBuffer& outBuffer);
+
+private:
+  AdjacencyLsaPublisher& m_adjacencyLsaPublisher;
+  CoordinateLsaPublisher& m_coordinateLsaPublisher;
+  NameLsaPublisher& m_nameLsaPublisher;
+
+public:
+  static const ndn::Name::Component DATASET_COMPONENT;
+};
+
+} // namespace nlsr
+
+#endif // NLSR_PUBLISHER_LSDB_STATUS_PUBLISHER_HPP
diff --git a/src/publisher/segment-publisher.hpp b/src/publisher/segment-publisher.hpp
new file mode 100644
index 0000000..cb311e9
--- /dev/null
+++ b/src/publisher/segment-publisher.hpp
@@ -0,0 +1,130 @@
+/* -*- 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 NLSR_PUBLISHER_SEGMENT_PUBLISHER_HPP
+#define NLSR_PUBLISHER_SEGMENT_PUBLISHER_HPP
+
+#include <ndn-cxx/encoding/encoding-buffer.hpp>
+#include <ndn-cxx/security/key-chain.hpp>
+
+namespace nlsr {
+
+/** \brief provides a publisher of Status Dataset or other segmented octet stream
+ *  \sa http://redmine.named-data.net/projects/nfd/wiki/StatusDataset
+ */
+template <class FaceBase>
+class SegmentPublisher : ndn::noncopyable
+{
+public:
+  SegmentPublisher(FaceBase& face,
+                   const ndn::Name& prefix,
+                   ndn::KeyChain& keyChain,
+                   const ndn::time::milliseconds& freshnessPeriod = getDefaultFreshness())
+    : m_face(face)
+    , m_prefix(prefix)
+    , m_keyChain(keyChain)
+    , m_freshnessPeriod(freshnessPeriod)
+  {
+  }
+
+  virtual
+  ~SegmentPublisher()
+  {
+  }
+
+  static size_t
+  getMaxSegmentSize()
+  {
+    static const size_t MAX_SEGMENT_SIZE = ndn::MAX_NDN_PACKET_SIZE >> 1;
+    return MAX_SEGMENT_SIZE;
+  }
+
+  static constexpr ndn::time::milliseconds
+  getDefaultFreshness()
+  {
+    return ndn::time::milliseconds(1000);
+  }
+
+  void
+  publish()
+  {
+    ndn::EncodingBuffer buffer;
+    generate(buffer);
+
+    const uint8_t* rawBuffer = buffer.buf();
+    const uint8_t* segmentBegin = rawBuffer;
+    const uint8_t* end = rawBuffer + buffer.size();
+
+    ndn::Name segmentPrefix(m_prefix);
+    segmentPrefix.appendVersion();
+
+    uint64_t segmentNo = 0;
+    do {
+      const uint8_t* segmentEnd = segmentBegin + getMaxSegmentSize();
+      if (segmentEnd > end) {
+        segmentEnd = end;
+      }
+
+      ndn::Name segmentName(segmentPrefix);
+      segmentName.appendSegment(segmentNo);
+
+      ndn::shared_ptr<ndn::Data> data = ndn::make_shared<ndn::Data>(segmentName);
+      data->setContent(segmentBegin, segmentEnd - segmentBegin);
+      data->setFreshnessPeriod(m_freshnessPeriod);
+
+      segmentBegin = segmentEnd;
+      if (segmentBegin >= end) {
+        data->setFinalBlockId(segmentName[-1]);
+      }
+
+      publishSegment(data);
+      ++segmentNo;
+    } while (segmentBegin < end);
+  }
+
+protected:
+  /** \brief In a derived class, write the octets into outBuffer.
+   */
+  virtual size_t
+  generate(ndn::EncodingBuffer& outBuffer) = 0;
+
+private:
+  void
+  publishSegment(ndn::shared_ptr<ndn::Data>& data)
+  {
+    m_keyChain.sign(*data);
+    m_face.put(*data);
+  }
+
+private:
+  FaceBase& m_face;
+  const ndn::Name m_prefix;
+  ndn::KeyChain& m_keyChain;
+  const ndn::time::milliseconds m_freshnessPeriod;
+};
+
+} // namespace nlsr
+
+#endif // NLSR_PUBLISHER_SEGMENT_PUBLISHER_HPP
diff --git a/src/tlv/lsa-info.cpp b/src/tlv/lsa-info.cpp
index 5349c31..e81bdc9 100644
--- a/src/tlv/lsa-info.cpp
+++ b/src/tlv/lsa-info.cpp
@@ -170,5 +170,21 @@
   return os;
 }
 
+std::shared_ptr<LsaInfo>
+makeLsaInfo(const Lsa& lsa)
+{
+  std::shared_ptr<LsaInfo> lsaInfo = std::make_shared<LsaInfo>();
+
+  lsaInfo->setOriginRouter(lsa.getOrigRouter());
+  lsaInfo->setSequenceNumber(lsa.getLsSeqNo());
+
+  ndn::time::system_clock::duration duration
+    = lsa.getExpirationTimePoint() - ndn::time::system_clock::now();
+
+  lsaInfo->setExpirationPeriod(ndn::time::duration_cast<ndn::time::milliseconds>(duration));
+
+  return lsaInfo;
+}
+
 } // namespace tlv
 } // namespace nlsr
diff --git a/src/tlv/lsa-info.hpp b/src/tlv/lsa-info.hpp
index a5cf7bf..0cb186c 100644
--- a/src/tlv/lsa-info.hpp
+++ b/src/tlv/lsa-info.hpp
@@ -28,6 +28,8 @@
 #include <ndn-cxx/encoding/tlv.hpp>
 #include <ndn-cxx/name.hpp>
 
+#include "lsa.hpp"
+
 namespace nlsr {
 namespace tlv  {
 
@@ -134,6 +136,9 @@
 std::ostream&
 operator<<(std::ostream& os, const LsaInfo& lsaInfo);
 
+std::shared_ptr<LsaInfo>
+makeLsaInfo(const Lsa& lsa);
+
 } // namespace tlv
 } // namespace nlsr
 
