diff --git a/tools/ndns-update.cpp b/tools/ndns-update.cpp
new file mode 100644
index 0000000..bb08adf
--- /dev/null
+++ b/tools/ndns-update.cpp
@@ -0,0 +1,352 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014, Regents of the University of California.
+ *
+ * This file is part of NDNS (Named Data Networking Domain Name Service).
+ * See AUTHORS.md for complete list of NDNS authors and contributors.
+ *
+ * NDNS 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.
+ *
+ * NDNS 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
+ * NDNS, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "clients/response.hpp"
+#include "clients/query.hpp"
+#include "ndns-label.hpp"
+#include "validator.hpp"
+#include "ndns-enum.hpp"
+#include "ndns-tlv.hpp"
+#include "logger.hpp"
+#include "daemon/db-mgr.hpp"
+#include "util/util.hpp"
+
+#include <ndn-cxx/security/key-chain.hpp>
+#include <ndn-cxx/data.hpp>
+#include <ndn-cxx/util/io.hpp>
+#include <ndn-cxx/encoding/block.hpp>
+#include <ndn-cxx/encoding/block-helpers.hpp>
+#include <boost/noncopyable.hpp>
+#include <boost/program_options.hpp>
+#include <boost/asio.hpp>
+#include <boost/filesystem.hpp>
+
+#include <string>
+#include <tuple>
+
+namespace ndn {
+namespace ndns {
+NDNS_LOG_INIT("NdnsUpdate");
+
+class NdnsUpdate : noncopyable
+{
+public:
+  NdnsUpdate(const Name& hint, const Name& zone, const Name& rrLabel,
+             const name::Component& rrType, NdnsType ndnsType, const Name& certName,
+             Face& face)
+    : m_queryType(rrType == label::CERT_RR_TYPE ?
+                  label::NDNS_CERT_QUERY : label::NDNS_ITERATIVE_QUERY)
+    , m_rrType(rrType)
+    , m_hint(hint)
+    , m_zone(zone)
+    , m_certName(certName)
+    , m_interestLifetime(DEFAULT_INTEREST_LIFETIME)
+    , m_face(face)
+    , m_validator(face)
+    , m_hasError(false)
+  {
+    m_update.setZone(m_zone);
+    m_update.setRrLabel(rrLabel);
+    m_update.setQueryType(m_queryType);
+    m_update.setRrType(name::Component(rrType));
+    m_update.setNdnsType(ndnsType);
+  }
+
+  void
+  run()
+  {
+    NDNS_LOG_INFO(" =================================== "
+                  << "start to update RR at Zone = " << this->m_zone
+                  << " with rrLabel = " << this->m_update.getRrLabel()
+                  << " and rrType = " << this->m_rrType
+                  << " =================================== ");
+
+    Interest interest = this->makeUpdateInterest();
+    NDNS_LOG_TRACE("[* <- *] send Update: " << m_update);
+    m_face.expressInterest(interest,
+                           bind(&NdnsUpdate::onData, this, _1, _2),
+                           bind(&NdnsUpdate::onTimeout, this, _1) //dynamic binding
+                           );
+    try {
+      m_face.processEvents();
+    }
+    catch (std::exception& e) {
+      NDNS_LOG_FATAL("Face fails to process events: " << e.what());
+      m_hasError = true;
+    }
+  }
+
+  void
+  stop()
+  {
+    m_face.getIoService().stop();
+  }
+
+private:
+  void
+  onData(const Interest& interest, const Data& data)
+  {
+    NDNS_LOG_INFO("get response of Update");
+    int ret = -1;
+    std::string msg;
+    std::tie(ret, msg) = this->parseResponse(data);
+    NDNS_LOG_INFO("Return Code: " << ret << ", and Update "
+                  << (ret == UPDATE_OK ? "succeeds" : "fails"));
+    if (ret != UPDATE_OK)
+      m_hasError = true;
+
+    if (!msg.empty()) {
+      NDNS_LOG_INFO("Return Msg: " << msg);
+    }
+
+    NDNS_LOG_INFO("to verify the response");
+    m_validator.validate(data,
+                         bind(&NdnsUpdate::onDataValidated, this, _1),
+                         bind(&NdnsUpdate::onDataValidationFailed, this, _1, _2)
+                         );
+  }
+
+  std::tuple<int, std::string>
+  parseResponse(const Data& data)
+  {
+    int ret = -1;
+    std::string msg;
+    Block blk = data.getContent();
+    blk.parse();
+    Block block = blk.blockFromValue();
+    block.parse();
+    Block::element_const_iterator val = block.elements_begin();
+    for (; val != block.elements_end(); ++val) {
+      if (val->type() == ndns::tlv::UpdateReturnCode) { // the first must be return code
+        ret = readNonNegativeInteger(*val);
+      }
+      else if (val->type() == ndns::tlv::UpdateReturnMsg) {
+        msg =  std::string(reinterpret_cast<const char*>(val->value()), val->value_size());
+      }
+    }
+
+    return std::make_tuple(ret, msg);
+  }
+
+  /**
+   * @brief construct a query (interest) which contains the update information
+   */
+  Interest
+  makeUpdateInterest()
+  {
+    shared_ptr<Data> data = m_update.toData();
+    m_keyChain.sign(*data, m_certName);
+
+    Query q(m_hint, m_zone, label::NDNS_ITERATIVE_QUERY);
+    q.setRrLabel(Name().append(data->wireEncode()));
+    q.setRrType(label::NDNS_UPDATE_LABEL);
+    q.setInterestLifetime(m_interestLifetime);
+
+    return q.toInterest();
+  }
+
+private:
+  void
+  onTimeout(const ndn::Interest& interest)
+  {
+    NDNS_LOG_TRACE("Update timeouts");
+    m_hasError = true;
+    this->stop();
+  }
+
+  void
+  onDataValidated(const shared_ptr<const Data>& data)
+  {
+    NDNS_LOG_INFO("data pass verification");
+    this->stop();
+  }
+
+  void
+  onDataValidationFailed(const shared_ptr<const Data>& data, const std::string& str)
+  {
+    NDNS_LOG_INFO("data does not pass verification");
+    m_hasError = true;
+    this->stop();
+  }
+
+public:
+  void
+  setUpdateAppContent(const Block& block)
+  {
+    m_update.setAppContent(block);
+  }
+
+  void
+  addUpdateRr(const Block& block)
+  {
+    m_update.addRr(block);
+  }
+
+  void
+  setInterestLifetime(const time::milliseconds& interestLifetime)
+  {
+    m_interestLifetime = interestLifetime;
+  }
+
+  const bool
+  hasError() const
+  {
+    return m_hasError;
+  }
+
+private:
+  name::Component m_queryType; ///< NDNS or KEY
+  name::Component m_rrType;
+
+  Name m_hint;
+  Name m_zone;
+  Name m_certName;
+  time::milliseconds m_interestLifetime;
+
+  Face& m_face;
+  Validator m_validator;
+  KeyChain m_keyChain;
+
+  Response m_update;
+  bool m_hasError;
+};
+
+} // namespace ndns
+} // namespace ndn
+
+int
+main(int argc, char* argv[])
+{
+  ndn::ndns::log::init();
+  using std::string;
+  using namespace ndn;
+  using namespace ndn::ndns;
+
+  Name hint;
+  Name zone;
+  int ttl = 4;
+  Name rrLabel;
+  string rrType = "TXT";
+  string ndnsTypeStr = "resp";
+  Name certName;
+  string content;
+  string contentFile;
+  ndn::Block block;
+  try {
+    namespace po = boost::program_options;
+    po::variables_map vm;
+
+    po::options_description generic("Generic Options");
+    generic.add_options()("help,h", "print help message");
+
+    po::options_description config("Configuration");
+    config.add_options()
+      ("hint,H", po::value<Name>(&hint), "forwarding hint")
+      ("ttl,T", po::value<int>(&ttl), "TTL of query. default: 4 sec")
+      ("rrtype,t", po::value<string>(&rrType), "set request RR Type. default: TXT")
+      ("ndnsType,n", po::value<string>(&ndnsTypeStr), "Set the ndnsType of the resource record. "
+       "Potential values are [resp|nack|auth|raw]. Default: resp")
+      ("cert,c", po::value<Name>(&certName), "set the name of certificate to sign the update")
+      ("content,o", po::value<string>(&content), "set the content of the RR")
+      ("contentFile,f", po::value<string>(&contentFile), "set the path of file which contain"
+       " content of the RR in base64 format")
+      ;
+
+    po::options_description hidden("Hidden Options");
+    hidden.add_options()
+      ("zone,z", po::value<Name>(&zone), "zone the record is delegated")
+      ("rrlabel,l", po::value<Name>(&rrLabel), "set request RR Label")
+      ;
+    po::positional_options_description postion;
+    postion.add("zone", 1);
+    postion.add("rrlabel", 1);
+
+    po::options_description cmdline_options;
+    cmdline_options.add(generic).add(config).add(hidden);
+
+    po::options_description config_file_options;
+    config_file_options.add(config).add(hidden);
+
+    po::options_description visible("Allowed options");
+    visible.add(generic).add(config);
+
+    po::parsed_options parsed =
+      po::command_line_parser(argc, argv).options(cmdline_options).positional(postion).run();
+
+    po::store(parsed, vm);
+    po::notify(vm);
+
+    if (vm.count("help")) {
+      std::cout << "Usage: ndns-update zone rrLabel [-t rrType] [-w waitingSec] "
+        "[-H hint] [-n NdnsType] [-c cert] [-f contentFile]|[-o content]" << std::endl;
+      std::cout << visible << std::endl;
+      return 0;
+    }
+
+    KeyChain keyChain;
+    if (certName.empty()) {
+      certName = keyChain.getDefaultCertificateName().toUri();
+    }
+    else {
+      if (!keyChain.doesCertificateExist(certName)) {
+        std::cerr << "certificate: " << certName << " does not exist" << std::endl;
+        return 0;
+      }
+    }
+
+    if (vm.count("content") && vm.count("contentFile")) {
+      std::cerr <<"both content and contentFile are set. Only one is allowed" << std::endl;
+      return 0;
+    }
+
+    if (!contentFile.empty()) {
+      shared_ptr<ndn::Data> data = ndn::io::load<ndn::Data>(contentFile);
+      block = data->wireEncode();
+    }
+    else {
+      if (!content.empty())
+        block = ndn::dataBlock(ndn::ndns::tlv::RrData, content.c_str(), content.size());
+    }
+  }
+  catch (const std::exception& ex) {
+    std::cerr << "Parameter Error: " << ex.what() << std::endl;
+    return 0;
+  }
+
+  Face face;
+  NdnsType ndnsType = toNdnsType(ndnsTypeStr);
+
+  NdnsUpdate update(hint, zone, rrLabel, ndn::name::Component(rrType),
+                    ndnsType, certName, face);
+  update.setInterestLifetime(ndn::time::seconds(ttl));
+
+  if (!block.empty()) {
+    if (ndnsType == ndn::ndns::NDNS_RAW)
+      update.setUpdateAppContent(block);
+    else
+      update.addUpdateRr(block);
+  }
+
+  update.run();
+
+  if (update.hasError())
+    return 1;
+  else
+    return 0;
+}
