mgmt: add support for FIB enumeration protocol

refs: #1192

Change-Id: If9198c7d90d8882e9590ce93165667923df59a03
diff --git a/daemon/mgmt/fib-manager.cpp b/daemon/mgmt/fib-manager.cpp
index 0ffe333..9ce7a6f 100644
--- a/daemon/mgmt/fib-manager.cpp
+++ b/daemon/mgmt/fib-manager.cpp
@@ -28,30 +28,46 @@
   FibManager::COMMAND_UNSIGNED_NCOMPS +
   4; // (timestamp, nonce, signed info tlv, signature tlv)
 
-const FibManager::VerbAndProcessor FibManager::COMMAND_VERBS[] =
+const FibManager::SignedVerbAndProcessor FibManager::SIGNED_COMMAND_VERBS[] =
   {
 
-    VerbAndProcessor(
-                     Name::Component("add-nexthop"),
-                     &FibManager::addNextHop
-                     ),
+    SignedVerbAndProcessor(
+                           Name::Component("add-nexthop"),
+                           &FibManager::addNextHop
+                           ),
 
-    VerbAndProcessor(
-                     Name::Component("remove-nexthop"),
-                     &FibManager::removeNextHop
-                     ),
+    SignedVerbAndProcessor(
+                           Name::Component("remove-nexthop"),
+                           &FibManager::removeNextHop
+                           ),
 
   };
 
+const FibManager::UnsignedVerbAndProcessor FibManager::UNSIGNED_COMMAND_VERBS[] =
+  {
+    UnsignedVerbAndProcessor(
+                             Name::Component("list"),
+                             &FibManager::listEntries
+                             ),
+  };
+
+const Name FibManager::LIST_COMMAND_PREFIX("/localhost/nfd/fib/list");
+const size_t FibManager::LIST_COMMAND_NCOMPS = LIST_COMMAND_PREFIX.size();
+
+
 FibManager::FibManager(Fib& fib,
                        function<shared_ptr<Face>(FaceId)> getFace,
                        shared_ptr<InternalFace> face)
-  : ManagerBase(face, FIB_PRIVILEGE),
-    m_managedFib(fib),
-    m_getFace(getFace),
-    m_verbDispatch(COMMAND_VERBS,
-                   COMMAND_VERBS +
-                   (sizeof(COMMAND_VERBS) / sizeof(VerbAndProcessor)))
+  : ManagerBase(face, FIB_PRIVILEGE)
+  , m_managedFib(fib)
+  , m_getFace(getFace)
+  , m_fibEnumerationPublisher(fib, face, LIST_COMMAND_PREFIX)
+  , m_signedVerbDispatch(SIGNED_COMMAND_VERBS,
+                         SIGNED_COMMAND_VERBS +
+                         (sizeof(SIGNED_COMMAND_VERBS) / sizeof(SignedVerbAndProcessor)))
+  , m_unsignedVerbDispatch(UNSIGNED_COMMAND_VERBS,
+                           UNSIGNED_COMMAND_VERBS +
+                           (sizeof(UNSIGNED_COMMAND_VERBS) / sizeof(UnsignedVerbAndProcessor)))
 {
   face->setInterestFilter("/localhost/nfd/fib",
                           bind(&FibManager::onFibRequest, this, _2));
@@ -67,28 +83,32 @@
 {
   const Name& command = request.getName();
   const size_t commandNComps = command.size();
+  const Name::Component& verb = command.get(COMMAND_PREFIX.size());
 
-  if (COMMAND_UNSIGNED_NCOMPS <= commandNComps &&
+  UnsignedVerbDispatchTable::const_iterator unsignedVerbProcessor = m_unsignedVerbDispatch.find(verb);
+  if (unsignedVerbProcessor != m_unsignedVerbDispatch.end())
+    {
+      NFD_LOG_INFO("command result: processing verb: " << verb);
+      (unsignedVerbProcessor->second)(this, boost::cref(request));
+    }
+  else if (COMMAND_UNSIGNED_NCOMPS <= commandNComps &&
       commandNComps < COMMAND_SIGNED_NCOMPS)
     {
       NFD_LOG_INFO("command result: unsigned verb: " << command);
       sendResponse(command, 401, "Signature required");
-
-      return;
     }
   else if (commandNComps < COMMAND_SIGNED_NCOMPS ||
       !COMMAND_PREFIX.isPrefixOf(command))
     {
       NFD_LOG_INFO("command result: malformed");
       sendResponse(command, 400, "Malformed command");
-      return;
     }
-
-  validate(request,
-           bind(&FibManager::onValidatedFibRequest,
-                this, _1),
-           bind(&ManagerBase::onCommandValidationFailed,
-                this, _1, _2));
+  else
+    {
+      validate(request,
+               bind(&FibManager::onValidatedFibRequest, this, _1),
+               bind(&ManagerBase::onCommandValidationFailed, this, _1, _2));
+    }
 }
 
 void
@@ -97,8 +117,8 @@
   const Name& command = request->getName();
   const Name::Component& verb = command.get(COMMAND_PREFIX.size());
 
-  VerbDispatchTable::const_iterator verbProcessor = m_verbDispatch.find (verb);
-  if (verbProcessor != m_verbDispatch.end())
+  SignedVerbDispatchTable::const_iterator signedVerbProcessor = m_signedVerbDispatch.find (verb);
+  if (signedVerbProcessor != m_signedVerbDispatch.end())
     {
       FibManagementOptions options;
       if (!extractOptions(*request, options))
@@ -110,7 +130,7 @@
 
       NFD_LOG_INFO("command result: processing verb: " << verb);
       ControlResponse response;
-      (verbProcessor->second)(this, options, response);
+      (signedVerbProcessor->second)(this, options, response);
       sendResponse(command, response);
     }
   else
@@ -214,4 +234,21 @@
     }
 }
 
+void
+FibManager::listEntries(const Interest& request)
+{
+  const Name& command = request.getName();
+  const size_t commandNComps = command.size();
+
+  if (commandNComps < LIST_COMMAND_NCOMPS ||
+      !LIST_COMMAND_PREFIX.isPrefixOf(command))
+    {
+      NFD_LOG_INFO("command result: malformed");
+      sendResponse(command, 400, "Malformed command");
+      return;
+    }
+
+  m_fibEnumerationPublisher.publish();
+}
+
 } // namespace nfd