diff --git a/tools/ping/ndn-ping-server.cpp b/tools/ping/ndn-ping-server.cpp
deleted file mode 100644
index 437c529..0000000
--- a/tools/ping/ndn-ping-server.cpp
+++ /dev/null
@@ -1,255 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Arizona Board of Regents.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-/**
- * Copyright (C) 2014 Arizona Board of Regents
- *
- * This file is part of ndn-tlv-ping (Ping Application for Named Data Networking).
- *
- * ndn-tlv-ping is a 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.
- *
- * ndn-tlv-ping 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
- * ndn-tlv-ping, e.g., in LICENSE file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author: Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
- */
-
-#include "core/version.hpp"
-
-namespace ndn {
-namespace ping {
-
-class NdnPingServer : boost::noncopyable
-{
-public:
-  explicit
-  NdnPingServer(char* programName)
-    : m_programName(programName)
-    , m_hasError(false)
-    , m_isPrintTimestampSet(false)
-    , m_freshnessPeriod(getMinimumFreshnessPeriod())
-    , m_maximumPings(-1)
-    , m_totalPings(0)
-    , m_face(m_ioService)
-  {
-  }
-
-  void
-  usage()
-  {
-    std::cout << "\n Usage:\n " << m_programName << " ndn:/name/prefix [options]\n"
-        " Starts a NDN ping server that responds to Interests with name"
-        " ndn:/name/prefix/ping/number.\n"
-        "   [-x freshness] - set FreshnessSeconds\n"
-        "   [-p]           - specify number of pings to be satisfied (>=1)\n"
-        "   [-t]           - print timestamp\n"
-        "   [-h]           - print this message and exit\n\n";
-    exit(1);
-  }
-
-  time::milliseconds
-  getMinimumFreshnessPeriod()
-  {
-    return time::milliseconds(1000);
-  }
-
-  void
-  setFreshnessPeriod(int freshnessPeriod)
-  {
-    if (freshnessPeriod <= 0)
-      usage();
-
-    m_freshnessPeriod = time::milliseconds(freshnessPeriod);
-  }
-
-  void
-  setMaximumPings(int maximumPings)
-  {
-    if (maximumPings <= 0)
-      usage();
-
-    m_maximumPings = maximumPings;
-  }
-
-  void
-  setPrefix(char* prefix)
-  {
-    m_prefix = prefix;
-  }
-
-  void
-  setPrintTimestamp()
-  {
-    m_isPrintTimestampSet = true;
-  }
-
-  bool
-  hasError() const
-  {
-    return m_hasError;
-  }
-
-  void
-  onInterest(const Name& name, const Interest& interest)
-  {
-    Name interestName = interest.getName();
-
-    if (m_isPrintTimestampSet)
-      std::cout << time::toIsoString(time::system_clock::now())  << " - ";
-    std::cout << "Interest Received - Ping Reference = "
-              << interestName.at(-1).toUri() << std::endl;
-
-    char responseContent[] = "NDN TLV Ping Response";
-    shared_ptr<Data> data = make_shared<Data>(interestName);
-    data->setFreshnessPeriod(m_freshnessPeriod);
-    data->setContent(reinterpret_cast<const uint8_t*>(responseContent),
-                     sizeof(responseContent));
-    m_keyChain.sign(*data);
-    m_face.put(*data);
-
-    ++m_totalPings;
-    if (m_maximumPings > 0 && m_maximumPings == m_totalPings) {
-      std::cout << "\n\nTotal Ping Interests Processed = " << m_totalPings << std::endl;
-      std::cout << "Shutting Down Ping Server (" << m_name << ").\n" << std::endl;
-      m_face.shutdown();
-      m_ioService.stop();
-    }
-  }
-
-  void
-  onRegisterFailed(const ndn::Name& prefix, const std::string& reason)
-  {
-    std::cerr << "ERROR: Failed to register prefix in local hub's daemon" << std::endl;
-    std::cerr << "REASON: " << reason << std::endl;
-    m_hasError = true;
-    m_face.shutdown();
-    m_ioService.stop();
-  }
-
-  void
-  signalHandler()
-  {
-    std::cout << "\n\nTotal Ping Interests Processed = " << m_totalPings << std::endl;
-    std::cout << "Shutting Down Ping Server (" << m_name.toUri() << ").\n" << std::endl;
-    m_face.shutdown();
-    exit(1);
-  }
-
-  void
-  run()
-  {
-    std::cout << "\n=== Ping Server " << m_prefix <<" ===\n" << std::endl;
-
-    boost::asio::signal_set signalSet(m_ioService, SIGINT, SIGTERM);
-    signalSet.async_wait(bind([this]() { signalHandler(); }));
-
-    m_name = m_prefix;
-    m_name.append("ping");
-    m_face.setInterestFilter(m_name,
-                             bind(&NdnPingServer::onInterest,
-                                  this, _1, _2),
-                             bind(&NdnPingServer::onRegisterFailed,
-                                  this, _1,_2));
-
-    try {
-      m_face.processEvents();
-    }
-    catch (std::exception& e) {
-      std::cerr << "ERROR: " << e.what() << std::endl;
-      m_hasError = true;
-      m_ioService.stop();
-    }
-  }
-
-private:
-  char* m_programName;
-  bool m_hasError;
-  bool m_isPrintTimestampSet;
-  time::milliseconds m_freshnessPeriod;
-  int m_maximumPings;
-  int m_totalPings;
-
-  char* m_prefix;
-  Name m_name;
-
-  boost::asio::io_service m_ioService;
-  KeyChain m_keyChain;
-  Face m_face;
-};
-
-int
-main(int argc, char* argv[])
-{
-  int res;
-
-  NdnPingServer program(argv[0]);
-  while ((res = getopt(argc, argv, "hdtp:x:V")) != -1)
-    {
-      switch (res) {
-      case 'h':
-        program.usage();
-        break;
-      case 'p':
-        program.setMaximumPings(atoi(optarg));
-        break;
-      case 'x':
-        program.setFreshnessPeriod(atoi(optarg));
-        break;
-      case 't':
-        program.setPrintTimestamp();
-        break;
-      case 'V':
-        std::cout << "ndnpingserver " << tools::VERSION << std::endl;
-        return 0;
-     default:
-        program.usage();
-        break;
-      }
-    }
-
-  argc -= optind;
-  argv += optind;
-
-  if (argv[0] == 0)
-    program.usage();
-
-  program.setPrefix(argv[0]);
-  program.run();
-
-  std::cout << std::endl;
-
-  if (program.hasError())
-    return 1;
-  else
-    return 0;
-}
-
-} // namespace ping
-} // namespace ndn
-
-int
-main(int argc, char** argv)
-{
-  return ndn::ping::main(argc, argv);
-}
diff --git a/tools/ping/server/ndn-ping-server.cpp b/tools/ping/server/ndn-ping-server.cpp
new file mode 100644
index 0000000..998c40d
--- /dev/null
+++ b/tools/ping/server/ndn-ping-server.cpp
@@ -0,0 +1,197 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2015,  Arizona Board of Regents.
+ *
+ * This file is part of ndn-tools (Named Data Networking Essential Tools).
+ * See AUTHORS.md for complete list of ndn-tools authors and contributors.
+ *
+ * ndn-tools 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.
+ *
+ * ndn-tools 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
+ * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @author Eric Newberry <enewberry@email.arizona.edu>
+ * @author Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
+ */
+
+#include "core/common.hpp"
+#include "core/version.hpp"
+
+#include "ping-server.hpp"
+#include "tracer.hpp"
+
+namespace ndn {
+namespace ping {
+namespace server {
+
+static time::milliseconds
+getMinimumFreshnessPeriod()
+{
+  return time::milliseconds(1000);
+}
+
+static void
+usage(const boost::program_options::options_description& options)
+{
+  std::cout << "Usage: ndnpingserver [options] ndn:/name/prefix\n"
+      "\n"
+      "Starts a NDN ping server that responds to Interests with name"
+      "ndn:/name/prefix/ping/number.\n"
+      "\n";
+  std::cout << options;
+  exit(2);
+}
+
+static void
+printStatistics(PingServer& pingServer, Options& options)
+{
+  std::cout << "\n--- ping server " << options.prefix << " ---" << std::endl;
+  std::cout << pingServer.getNPings() << " packets processed" << std::endl;
+}
+
+/**
+ * @brief SIGINT handler: exits
+ * @param pingServer pingServer instance
+ * @param options options
+ */
+static void
+onSigInt(PingServer& pingServer, Options& options, Face& face)
+{
+  printStatistics(pingServer, options);
+  face.shutdown();
+  face.getIoService().stop();
+  exit(1);
+}
+
+/**
+ * @brief outputs errors to cerr
+ */
+static void
+onError(std::string msg)
+{
+  std::cerr << "ERROR: " << msg << std::endl;
+}
+
+int
+main(int argc, char* argv[])
+{
+  Options options;
+  options.freshnessPeriod = getMinimumFreshnessPeriod();
+  options.shouldLimitSatisfied = false;
+  options.nMaxPings = 0;
+  options.shouldPrintTimestamp = false;
+
+  namespace po = boost::program_options;
+
+  po::options_description visibleOptDesc("Allowed options");
+  visibleOptDesc.add_options()
+    ("help,h", "print this message and exit")
+    ("version,V", "display version and exit")
+    ("freshness,x", po::value<int>(),
+                   ("set freshness period in milliseconds (minimum " +
+                   std::to_string(getMinimumFreshnessPeriod().count()) + " ms)").c_str())
+    ("satisfy,p", po::value<int>(&options.nMaxPings), "set maximum number of pings to be satisfied")
+    ("timestamp,t", "log timestamp with responses")
+  ;
+  po::options_description hiddenOptDesc("Hidden options");
+  hiddenOptDesc.add_options()
+    ("prefix", po::value<std::string>(), "prefix to register")
+  ;
+
+  po::options_description optDesc("Allowed options");
+  optDesc.add(visibleOptDesc).add(hiddenOptDesc);
+
+  try {
+    po::positional_options_description optPos;
+    optPos.add("prefix", -1);
+
+    po::variables_map optVm;
+    po::store(po::command_line_parser(argc, argv).options(optDesc).positional(optPos).run(), optVm);
+    po::notify(optVm);
+
+    if (optVm.count("help") > 0) {
+      usage(visibleOptDesc);
+    }
+
+    if (optVm.count("version") > 0) {
+      std::cout << "ndnpingserver " << tools::VERSION << std::endl;
+      exit(0);
+    }
+
+    if (optVm.count("prefix") > 0) {
+      options.prefix = Name(optVm["prefix"].as<std::string>());
+    }
+    else {
+      std::cerr << "ERROR: No prefix specified" << std::endl;
+      usage(visibleOptDesc);
+    }
+
+    if (optVm.count("freshness") > 0) {
+      options.freshnessPeriod = time::milliseconds(optVm["freshness"].as<int>());
+
+      if (options.freshnessPeriod.count() < getMinimumFreshnessPeriod().count()) {
+        std::cerr << "ERROR: Specified FreshnessPeriod is less than the minimum "
+                  << getMinimumFreshnessPeriod() << std::endl;
+        usage(visibleOptDesc);
+      }
+    }
+
+    if (optVm.count("satisfy") > 0) {
+      options.shouldLimitSatisfied = true;
+
+      if (options.nMaxPings < 1) {
+        std::cerr << "ERROR: Maximum number of pings to satisfy must be greater than 0" << std::endl;
+        usage(visibleOptDesc);
+      }
+    }
+
+    if (optVm.count("timestamp") > 0) {
+      options.shouldPrintTimestamp = true;
+    }
+  }
+  catch (const po::error& e) {
+    std::cerr << "ERROR: " << e.what() << std::endl;
+    usage(visibleOptDesc);
+  }
+
+  boost::asio::io_service ioService;
+  Face face(ioService);
+  PingServer pingServer(face, options);
+  Tracer tracer(pingServer, options);
+
+  boost::asio::signal_set signalSetInt(face.getIoService(), SIGINT);
+  signalSetInt.async_wait(bind(&onSigInt, ref(pingServer), ref(options), ref(face)));
+
+  std::cout << "PING SERVER " << options.prefix << std::endl;
+
+  try {
+    pingServer.run();
+  }
+  catch (std::exception& e) {
+    onError(e.what());
+    face.getIoService().stop();
+    return 1;
+  }
+
+  printStatistics(pingServer, options);
+  face.shutdown();
+  face.getIoService().stop();
+
+  return 0;
+}
+
+} // namespace server
+} // namespace ping
+} // namespace ndn
+
+int
+main(int argc, char** argv)
+{
+  return ndn::ping::server::main(argc, argv);
+}
\ No newline at end of file
diff --git a/tools/ping/server/ping-server.cpp b/tools/ping/server/ping-server.cpp
new file mode 100644
index 0000000..e75f649
--- /dev/null
+++ b/tools/ping/server/ping-server.cpp
@@ -0,0 +1,86 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2015,  Arizona Board of Regents.
+ *
+ * This file is part of ndn-tools (Named Data Networking Essential Tools).
+ * See AUTHORS.md for complete list of ndn-tools authors and contributors.
+ *
+ * ndn-tools 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.
+ *
+ * ndn-tools 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
+ * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @author Eric Newberry <enewberry@email.arizona.edu>
+ * @author Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
+ */
+
+#include "ping-server.hpp"
+
+namespace ndn {
+namespace ping {
+namespace server {
+
+PingServer::PingServer(Face& face, const Options& options)
+  : m_options(options)
+  , m_name(options.prefix)
+  , m_nPings(0)
+  , m_face(face)
+{
+}
+
+void
+PingServer::run()
+{
+  m_name.append("ping");
+  m_face.setInterestFilter(m_name,
+                           bind(&PingServer::onInterest,
+                                this, _2),
+                           bind(&PingServer::onRegisterFailed,
+                                this, _2));
+
+  m_face.processEvents();
+}
+
+int
+PingServer::getNPings() const
+{
+  return m_nPings;
+}
+
+void
+PingServer::onInterest(const Interest& interest)
+{
+  Name interestName = interest.getName();
+
+  afterReceive(interestName);
+
+  char responseContent[] = "NDN TLV Ping Response";
+  shared_ptr<Data> data = make_shared<Data>(interestName);
+  data->setFreshnessPeriod(m_options.freshnessPeriod);
+  data->setContent(reinterpret_cast<const uint8_t*>(responseContent),
+                   sizeof(responseContent));
+  m_keyChain.sign(*data);
+  m_face.put(*data);
+
+  ++m_nPings;
+  if (m_options.shouldLimitSatisfied && m_options.nMaxPings > 0 && m_options.nMaxPings == m_nPings) {
+    m_face.shutdown();
+    m_face.getIoService().stop();
+  }
+}
+
+void
+PingServer::onRegisterFailed(const std::string& reason)
+{
+  throw "Failed to register prefix in local hub's daemon, REASON: " + reason;
+}
+
+} // namespace server
+} // namespace ping
+} // namespace ndn
\ No newline at end of file
diff --git a/tools/ping/server/ping-server.hpp b/tools/ping/server/ping-server.hpp
new file mode 100644
index 0000000..ddc3a19
--- /dev/null
+++ b/tools/ping/server/ping-server.hpp
@@ -0,0 +1,99 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2015,  Arizona Board of Regents.
+ *
+ * This file is part of ndn-tools (Named Data Networking Essential Tools).
+ * See AUTHORS.md for complete list of ndn-tools authors and contributors.
+ *
+ * ndn-tools 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.
+ *
+ * ndn-tools 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
+ * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @author Eric Newberry <enewberry@email.arizona.edu>
+ * @author Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
+ */
+
+#ifndef NDN_TOOLS_PING_SERVER_PING_SERVER_HPP
+#define NDN_TOOLS_PING_SERVER_PING_SERVER_HPP
+
+#include "core/common.hpp"
+
+namespace ndn {
+namespace ping {
+namespace server {
+
+/**
+ * @brief options for ndnping server
+ */
+struct Options
+{
+  Name prefix;                        //!< prefix to register
+  time::milliseconds freshnessPeriod; //!< freshness period
+  bool shouldLimitSatisfied;          //!< should limit the number of pings satisfied
+  int nMaxPings;                      //!< max number of pings to satisfy
+  bool shouldPrintTimestamp;          //!< print timestamp when response sent
+};
+
+/**
+ * @brief NDN modular ping server
+ */
+class PingServer : noncopyable
+{
+public:
+  PingServer(Face& face, const Options& options);
+
+  /**
+   * Signals when Interest received
+   * @param name incoming interest name
+   */
+  signal::Signal<PingServer, Name> afterReceive;
+
+  /** @brief starts ping server
+   *
+   *  If options.shouldLimitSatisfied is false, this method does not return unless there's an error.
+   *  Otherwise, this method returns when options.nMaxPings Interests are processed.
+   */
+  void
+  run();
+
+  /**
+   * @brief gets the number of pings received
+   */
+  int
+  getNPings() const;
+
+private:
+  /**
+   * Called when interest received
+   * @param interest incoming interest
+   */
+  void
+  onInterest(const Interest& interest);
+
+  /**
+   * Called when prefix registration failed
+   * @param reason reason for failure
+   */
+  void
+  onRegisterFailed(const std::string& reason);
+
+private:
+  const Options& m_options;
+  Name m_name;
+  KeyChain m_keyChain;
+  int m_nPings;
+  Face& m_face;
+};
+
+} // namespace server
+} // namespace ping
+} // namespace ndn
+
+#endif //NDN_TOOLS_PING_SERVER_PING_SERVER_HPP
\ No newline at end of file
diff --git a/tools/ping/server/tracer.cpp b/tools/ping/server/tracer.cpp
new file mode 100644
index 0000000..fa4e2c8
--- /dev/null
+++ b/tools/ping/server/tracer.cpp
@@ -0,0 +1,46 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2015,  Arizona Board of Regents.
+ *
+ * This file is part of ndn-tools (Named Data Networking Essential Tools).
+ * See AUTHORS.md for complete list of ndn-tools authors and contributors.
+ *
+ * ndn-tools 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.
+ *
+ * ndn-tools 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
+ * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @author Eric Newberry <enewberry@email.arizona.edu>
+ */
+
+#include "tracer.hpp"
+
+namespace ndn {
+namespace ping {
+namespace server {
+
+Tracer::Tracer(PingServer& pingServer, const Options& options)
+  : m_options(options)
+{
+  pingServer.afterReceive.connect(bind(&Tracer::onReceive, this, _1));
+}
+
+void
+Tracer::onReceive(const Name& name)
+{
+  if (m_options.shouldPrintTimestamp) {
+    std::cout << time::toIsoString(time::system_clock::now())  << " - ";
+  }
+
+  std::cout << "interest received: seq=" << name.at(-1).toUri() << std::endl;
+}
+
+} // namespace server
+} // namespace ping
+} // namespace ndn
\ No newline at end of file
diff --git a/tools/ping/server/tracer.hpp b/tools/ping/server/tracer.hpp
new file mode 100644
index 0000000..1971f50
--- /dev/null
+++ b/tools/ping/server/tracer.hpp
@@ -0,0 +1,56 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2015,  Arizona Board of Regents.
+ *
+ * This file is part of ndn-tools (Named Data Networking Essential Tools).
+ * See AUTHORS.md for complete list of ndn-tools authors and contributors.
+ *
+ * ndn-tools 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.
+ *
+ * ndn-tools 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
+ * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @author Eric Newberry <enewberry@email.arizona.edu>
+ */
+
+#ifndef NDN_TOOLS_PING_SERVER_TRACER_HPP
+#define NDN_TOOLS_PING_SERVER_TRACER_HPP
+
+#include "core/common.hpp"
+
+#include "ping-server.hpp"
+
+namespace ndn {
+namespace ping {
+namespace server {
+
+/**
+ * @brief logs ping responses
+ */
+class Tracer : noncopyable
+{
+public:
+  Tracer(PingServer& pingServer, const Options& options);
+
+  /**
+   * Prints ping information when interest received
+   * @param name interest name received
+   */
+  void
+  onReceive(const Name& name);
+
+private:
+  const Options& m_options;
+};
+
+} // namespace server
+} // namespace ping
+} // namespace ndn
+
+#endif //NDN_TOOLS_PING_SERVER_TRACER_HPP
\ No newline at end of file
diff --git a/tools/ping/wscript b/tools/ping/wscript
index 0301eeb..575e395 100644
--- a/tools/ping/wscript
+++ b/tools/ping/wscript
@@ -12,6 +12,6 @@
     bld.program(
         features='cxx',
         target='../../bin/ndnpingserver',
-        source='ndn-ping-server.cpp',
+        source=bld.path.ant_glob('server/*.cpp'),
         use='core-objects',
         )
