diff --git a/src/nrd.cpp b/src/nrd.cpp
new file mode 100644
index 0000000..0928a63
--- /dev/null
+++ b/src/nrd.cpp
@@ -0,0 +1,260 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "nrd.hpp"
+
+namespace ndn {
+namespace nrd {
+
+const Name Nrd::COMMAND_PREFIX = "/localhost/nrd";
+
+const size_t Nrd::COMMAND_UNSIGNED_NCOMPS =
+  Nrd::COMMAND_PREFIX.size() +
+  1 + // verb
+  1;  // verb options
+
+const size_t Nrd::COMMAND_SIGNED_NCOMPS =
+  Nrd::COMMAND_UNSIGNED_NCOMPS +
+  4; // (timestamp, nonce, signed info tlv, signature tlv)
+
+const Nrd::VerbAndProcessor Nrd::COMMAND_VERBS[] =
+  {
+    VerbAndProcessor(
+                     Name::Component("register"),
+                     &Nrd::insertEntry
+                     ),
+
+    VerbAndProcessor(
+                     Name::Component("unregister"),
+                     &Nrd::deleteEntry
+                     ),
+  };
+
+void
+setInterestFilterFailed(const Name& name, const std::string& msg) 
+{
+  std::cerr << "Error in setting interest filter (" << name << "): " << msg << std::endl;
+}
+
+Nrd::Nrd()
+  : m_nfdController(new nfd::Controller(m_face)),
+    m_verbDispatch(COMMAND_VERBS,
+                   COMMAND_VERBS + (sizeof(COMMAND_VERBS) / sizeof(VerbAndProcessor)))
+{
+  m_face.setController(m_nfdController);
+  m_face.setInterestFilter("/localhost/nrd",
+                           bind(&Nrd::onRibRequest, this, _2),
+                           bind(&setInterestFilterFailed, _1, _2));
+}
+
+void
+Nrd::sendResponse(const Name& name,
+                  const nfd::ControlResponse& response)
+{
+  const Block& encodedControl = response.wireEncode();
+
+  Data responseData(name);
+  responseData.setContent(encodedControl);
+
+  m_keyChain.sign(responseData);
+  m_face.put(responseData);
+}
+
+void
+Nrd::sendResponse(const Name& name,
+                  uint32_t code,
+                  const std::string& text)
+{
+  nfd::ControlResponse response(code, text);
+  sendResponse(name, response);
+}
+
+void
+Nrd::onRibRequest(const Interest& request)
+{
+  const Name& command = request.getName();
+  const size_t commandNComps = command.size();
+
+  if (COMMAND_UNSIGNED_NCOMPS <= commandNComps &&
+      commandNComps < COMMAND_SIGNED_NCOMPS)
+    {
+      std::cerr << "Error: Signature required" << std::endl;
+      sendResponse(command, 401, "Signature required");
+      return;
+    }
+  else if (commandNComps < COMMAND_SIGNED_NCOMPS ||
+           !COMMAND_PREFIX.isPrefixOf(command))
+    {
+      std::cerr << "Error: Malformed Command" << std::endl;
+      sendResponse(command, 400, "Malformed command");
+      return;
+    }
+
+  const Name::Component& verb = command.get(COMMAND_PREFIX.size());
+  VerbDispatchTable::const_iterator verbProcessor = m_verbDispatch.find(verb);
+
+  if (verbProcessor != m_verbDispatch.end())
+    {
+      PrefixRegOptions options;
+      if (!extractOptions(request, options))
+        {
+          sendResponse(command, 400, "Malformed command");
+          return;
+        }
+
+      /// \todo authorize command
+      if (false)
+        {
+          sendResponse(request.getName(), 403, "Unauthorized command");
+          return;
+        }
+
+      // \todo add proper log support
+      std::cout << "Received options (name, faceid, cost): " << options.getName() << 
+                   ", " << options.getFaceId() << ", "  << options.getCost() << std::endl;
+
+      nfd::ControlResponse response;
+      (verbProcessor->second)(this, request, options);
+    }
+  else
+    {
+      sendResponse(request.getName(), 501, "Unsupported command");
+    }
+}
+
+bool
+Nrd::extractOptions(const Interest& request,
+                    PrefixRegOptions& extractedOptions)
+{
+  const Name& command = request.getName();
+  const size_t optionCompIndex = COMMAND_PREFIX.size() + 1;
+
+  try
+    {
+      Block rawOptions = request.getName()[optionCompIndex].blockFromValue();
+      extractedOptions.wireDecode(rawOptions);
+    }
+  catch (const ndn::Tlv::Error& e)
+    {
+      return false;
+    }
+
+  if (extractedOptions.getFaceId() == 0)
+    {
+      std::cout <<"IncomingFaceId: " << request.getIncomingFaceId() << std::endl;
+      extractedOptions.setFaceId(request.getIncomingFaceId());
+    }
+  return true;
+}
+
+void
+Nrd::onCommandError(const std::string& error, 
+                    const Interest& request, 
+                    const PrefixRegOptions& options)
+{
+  nfd::ControlResponse response;
+  
+  response.setCode(400);
+  response.setText(error);
+  
+  std::cout << "Error: " << error << std::endl;
+  sendResponse(request.getName(), response);
+  m_managedRib.erase(options);
+}
+
+void
+Nrd::onUnRegSuccess(const Interest& request, const PrefixRegOptions& options)
+{
+  nfd::ControlResponse response;
+  
+  response.setCode(200);
+  response.setText("Success");
+  response.setBody(options.wireEncode());
+ 
+  std::cout << "Success: Name unregistered (" << 
+                options.getName() << ", " << 
+                options.getFaceId() << ")" << std::endl;
+  sendResponse(request.getName(), response);
+  m_managedRib.erase(options);
+}
+
+void
+Nrd::onRegSuccess(const Interest& request, const PrefixRegOptions& options)
+{
+  nfd::ControlResponse response;
+  
+  response.setCode(200);
+  response.setText("Success");
+  response.setBody(options.wireEncode());
+  
+  std::cout << "Success: Name registered (" << options.getName() << ", " << 
+                                               options.getFaceId() << ")" << std::endl;
+  sendResponse(request.getName(), response);
+}
+
+
+void
+Nrd::insertEntry(const Interest& request, const PrefixRegOptions& options)
+{
+  // For right now, just pass the options to fib as it is,
+  // without processing flags. Later options will be first added to
+  // Rib tree, then nrd will generate fib updates based on flags and then
+  // will add next hops one by one..
+  m_managedRib.insert(options);
+  m_nfdController->fibAddNextHop(options.getName(), options.getFaceId(),
+                                 options.getCost(),
+                                 bind(&Nrd::onRegSuccess, this, request, options),
+                                 bind(&Nrd::onCommandError, this, _1, request, options));
+}
+
+
+void
+Nrd::deleteEntry(const Interest& request, const PrefixRegOptions& options)
+{
+  m_nfdController->fibRemoveNextHop(options.getName(),
+                                    options.getFaceId(),
+                                    bind(&Nrd::onUnRegSuccess, this, request, options),
+                                    bind(&Nrd::onCommandError, this, _1, request, options));
+}
+
+
+void
+Nrd::listen()
+{
+  std::cout << "NRD started: listening for incoming interests" << std::endl;
+  m_face.processEvents();
+}
+
+
+void
+Nrd::onControlHeaderSuccess()
+{
+  std::cout << "Local control header enabled" << std::endl;
+}
+
+
+void
+Nrd::onControlHeaderError()
+{
+  std::cout << "Error: couldn't enable local control header" << std::endl;
+  m_face.shutdown();
+}
+
+
+void
+Nrd::enableLocalControlHeader()
+{
+  Name enable("/localhost/nfd/control-header/in-faceid/enable");
+  Interest enableCommand(enable);
+ 
+  m_keyChain.sign(enableCommand);
+  m_face.expressInterest(enableCommand,
+                         ndn::bind(&Nrd::onControlHeaderSuccess, this),
+                         ndn::bind(&Nrd::onControlHeaderError, this));
+}
+
+} // namespace nrd
+} // namespace ndn
