diff --git a/src/util/util.hpp b/src/util/util.hpp
new file mode 100644
index 0000000..2733cf1
--- /dev/null
+++ b/src/util/util.hpp
@@ -0,0 +1,44 @@
+/* -*- 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/>.
+ */
+
+#ifndef NDNS_UTIL_UTIL_HPP
+#define NDNS_UTIL_UTIL_HPP
+
+namespace ndn {
+namespace ndns {
+
+NdnsType
+toNdnsType(const std::string& str)
+{
+  if (str == "resp")
+    return NDNS_RESP;
+  else if (str == "nack")
+    return NDNS_NACK;
+  else if (str == "auth")
+    return NDNS_AUTH;
+  else if (str == "raw")
+    return NDNS_RAW;
+  else
+    return NDNS_UNKNOWN;
+}
+
+} // namespace ndns
+} // namespace ndn
+
+#endif // NDNS_UTIL_UTIL_HPP
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;
+}
