blob: 9824d6426d5ad14fca6a31412da0dcc2ba36f18e [file] [log] [blame]
Alexander Afanasyev4a771362014-04-24 21:29:33 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
jeraldabrahamb6dde382014-03-19 18:58:09 -07002/**
Junxiao Shi78926c92015-02-28 22:56:06 -07003 * Copyright (c) 2014-2015, Regents of the University of California,
4 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
jeraldabrahamb6dde382014-03-19 18:58:09 -070010 *
Alexander Afanasyev4a771362014-04-24 21:29:33 -070011 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24 *
25 * @author Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
jeraldabrahamb6dde382014-03-19 18:58:09 -070026 */
27
Alexander Afanasyevb47d5382014-05-05 14:35:03 -070028#include "version.hpp"
29
Alexander Afanasyev4a771362014-04-24 21:29:33 -070030#include <ndn-cxx/face.hpp>
31#include <ndn-cxx/name.hpp>
32#include <ndn-cxx/interest.hpp>
Alexander Afanasyevb3893c92014-05-15 01:49:54 -070033#include <ndn-cxx/encoding/buffer-stream.hpp>
jeraldabrahamb6dde382014-03-19 18:58:09 -070034
Alexander Afanasyev4a771362014-04-24 21:29:33 -070035#include <ndn-cxx/management/nfd-forwarder-status.hpp>
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +030036#include <ndn-cxx/management/nfd-channel-status.hpp>
37#include <ndn-cxx/management/nfd-face-status.hpp>
38#include <ndn-cxx/management/nfd-fib-entry.hpp>
Chengyu Fan30aa2072014-07-20 13:52:32 -060039#include <ndn-cxx/management/nfd-rib-entry.hpp>
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +030040#include <ndn-cxx/management/nfd-strategy-choice.hpp>
jeraldabrahamb6dde382014-03-19 18:58:09 -070041
Alexander Afanasyevb3893c92014-05-15 01:49:54 -070042#include <boost/algorithm/string/replace.hpp>
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +030043#include <list>
Alexander Afanasyevb3893c92014-05-15 01:49:54 -070044
jeraldabrahamb6dde382014-03-19 18:58:09 -070045namespace ndn {
46
47class NfdStatus
48{
49public:
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -070050 explicit
jeraldabrahamb6dde382014-03-19 18:58:09 -070051 NfdStatus(char* toolName)
52 : m_toolName(toolName)
53 , m_needVersionRetrieval(false)
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +030054 , m_needChannelStatusRetrieval(false)
jeraldabrahamb6dde382014-03-19 18:58:09 -070055 , m_needFaceStatusRetrieval(false)
56 , m_needFibEnumerationRetrieval(false)
Chengyu Fan30aa2072014-07-20 13:52:32 -060057 , m_needRibStatusRetrieval(false)
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +030058 , m_needStrategyChoiceRetrieval(false)
59 , m_isOutputXml(false)
jeraldabrahamb6dde382014-03-19 18:58:09 -070060 {
61 }
62
63 void
64 usage()
65 {
Alexander Afanasyev60a7ba52014-03-23 11:23:06 -070066 std::cout << "Usage: \n " << m_toolName << " [options]\n\n"
67 "Show NFD version and status information\n\n"
68 "Options:\n"
69 " [-h] - print this help message\n"
jeraldabrahamb6dde382014-03-19 18:58:09 -070070 " [-v] - retrieve version information\n"
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +030071 " [-c] - retrieve channel status information\n"
jeraldabrahamb6dde382014-03-19 18:58:09 -070072 " [-f] - retrieve face status information\n"
Alexander Afanasyevb47d5382014-05-05 14:35:03 -070073 " [-b] - retrieve FIB information\n"
Chengyu Fan30aa2072014-07-20 13:52:32 -060074 " [-r] - retrieve RIB information\n"
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +030075 " [-s] - retrieve configured strategy choice for NDN namespaces\n"
Chengyu Fanee92fc72014-06-21 14:58:19 -060076 " [-x] - output NFD status information in XML format\n"
Alexander Afanasyevb47d5382014-05-05 14:35:03 -070077 "\n"
78 " [-V] - show version information of nfd-status and exit\n"
79 "\n"
Alexander Afanasyev60a7ba52014-03-23 11:23:06 -070080 "If no options are provided, all information is retrieved.\n"
Chengyu Fanee92fc72014-06-21 14:58:19 -060081 "If -x is provided, other options(-v, -c, etc.) are ignored, and all information is printed in XML format.\n"
Alexander Afanasyev60a7ba52014-03-23 11:23:06 -070082 ;
jeraldabrahamb6dde382014-03-19 18:58:09 -070083 }
84
85 void
86 enableVersionRetrieval()
87 {
88 m_needVersionRetrieval = true;
89 }
90
91 void
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +030092 enableChannelStatusRetrieval()
93 {
94 m_needChannelStatusRetrieval = true;
95 }
96
97 void
jeraldabrahamb6dde382014-03-19 18:58:09 -070098 enableFaceStatusRetrieval()
99 {
100 m_needFaceStatusRetrieval = true;
101 }
102
103 void
104 enableFibEnumerationRetrieval()
105 {
106 m_needFibEnumerationRetrieval = true;
107 }
108
109 void
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300110 enableStrategyChoiceRetrieval()
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600111 {
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300112 m_needStrategyChoiceRetrieval = true;
113 }
114
115 void
Chengyu Fan30aa2072014-07-20 13:52:32 -0600116 enableRibStatusRetrieval()
117 {
118 m_needRibStatusRetrieval = true;
119 }
120
121 void
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300122 enableXmlOutput()
123 {
124 m_isOutputXml = true;
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600125 }
126
127 void
jeraldabrahamb6dde382014-03-19 18:58:09 -0700128 onTimeout()
129 {
130 std::cerr << "Request timed out" << std::endl;
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300131
132 runNextStep();
jeraldabrahamb6dde382014-03-19 18:58:09 -0700133 }
134
135 void
136 fetchSegments(const Data& data, void (NfdStatus::*onDone)())
137 {
138 m_buffer->write((const char*)data.getContent().value(),
139 data.getContent().value_size());
140
141 uint64_t currentSegment = data.getName().get(-1).toSegment();
142
143 const name::Component& finalBlockId = data.getMetaInfo().getFinalBlockId();
144 if (finalBlockId.empty() ||
145 finalBlockId.toSegment() > currentSegment)
146 {
147 m_face.expressInterest(data.getName().getPrefix(-1).appendSegment(currentSegment+1),
148 bind(&NfdStatus::fetchSegments, this, _2, onDone),
149 bind(&NfdStatus::onTimeout, this));
150 }
151 else
152 {
153 return (this->*onDone)();
154 }
155 }
156
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300157 void
158 escapeSpecialCharacters(std::string *data)
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600159 {
160 using boost::algorithm::replace_all;
161 replace_all(*data, "&", "&amp;");
162 replace_all(*data, "\"", "&quot;");
163 replace_all(*data, "\'", "&apos;");
164 replace_all(*data, "<", "&lt;");
165 replace_all(*data, ">", "&gt;");
166 }
167
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300168 //////////////////////////////////////////////////////////////////////////////////
169 //////////////////////////////////////////////////////////////////////////////////
170
171 void
172 fetchVersionInformation()
173 {
174 Interest interest("/localhost/nfd/status");
175 interest.setChildSelector(1);
176 interest.setMustBeFresh(true);
177 m_face.expressInterest(
178 interest,
179 bind(&NfdStatus::afterFetchedVersionInformation, this, _2),
180 bind(&NfdStatus::onTimeout, this));
181 }
182
jeraldabrahamb6dde382014-03-19 18:58:09 -0700183 void
184 afterFetchedVersionInformation(const Data& data)
185 {
Junxiao Shi88d69372014-03-28 11:52:39 -0700186 nfd::ForwarderStatus status(data.getContent());
Chengyu Fan8a53caf2014-08-01 14:08:37 -0600187 std::string nfdId;
188 if (data.getSignature().hasKeyLocator())
189 {
190 const ndn::KeyLocator& locator = data.getSignature().getKeyLocator();
191 if (locator.getType() == KeyLocator::KeyLocator_Name)
192 nfdId = locator.getName().toUri();
193 //todo: KeyDigest supporting
194 }
195
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300196 if (m_isOutputXml)
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600197 {
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600198 std::cout << "<generalStatus>";
Chengyu Fan8a53caf2014-08-01 14:08:37 -0600199 std::cout << "<nfdId>"
200 << nfdId << "</nfdId>";
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600201 std::cout << "<version>"
202 << status.getNfdVersion() << "</version>";
203 std::cout << "<startTime>"
204 << time::toString(status.getStartTimestamp(), "%Y-%m-%dT%H:%M:%S%F")
205 << "</startTime>";
206 std::cout << "<currentTime>"
207 << time::toString(status.getCurrentTimestamp(), "%Y-%m-%dT%H:%M:%S%F")
208 << "</currentTime>";
209 std::cout << "<uptime>PT"
210 << time::duration_cast<time::seconds>(status.getCurrentTimestamp()
211 - status.getStartTimestamp()).count()
212 << "S</uptime>";
213 std::cout << "<nNameTreeEntries>" << status.getNNameTreeEntries()
214 << "</nNameTreeEntries>";
215 std::cout << "<nFibEntries>" << status.getNFibEntries()
216 << "</nFibEntries>";
217 std::cout << "<nPitEntries>" << status.getNPitEntries()
218 << "</nPitEntries>";
219 std::cout << "<nMeasurementsEntries>" << status.getNMeasurementsEntries()
220 << "</nMeasurementsEntries>";
221 std::cout << "<nCsEntries>" << status.getNCsEntries()
222 << "</nCsEntries>";
223 std::cout << "<packetCounters>";
224 std::cout << "<incomingPackets>";
225 std::cout << "<nInterests>" << status.getNInInterests()
226 << "</nInterests>";
227 std::cout << "<nDatas>" << status.getNInDatas()
228 << "</nDatas>";
229 std::cout << "</incomingPackets>";
230 std::cout << "<outgoingPackets>";
231 std::cout << "<nInterests>" << status.getNOutInterests()
232 << "</nInterests>";
233 std::cout << "<nDatas>" << status.getNOutDatas()
234 << "</nDatas>";
235 std::cout << "</outgoingPackets>";
236 std::cout << "</packetCounters>";
237 std::cout << "</generalStatus>";
238 }
239 else
240 {
241 std::cout << "General NFD status:" << std::endl;
Chengyu Fan8a53caf2014-08-01 14:08:37 -0600242 std::cout << " nfdId="
243 << nfdId << std::endl;
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600244 std::cout << " version="
245 << status.getNfdVersion() << std::endl;
246 std::cout << " startTime="
247 << time::toIsoString(status.getStartTimestamp()) << std::endl;
248 std::cout << " currentTime="
249 << time::toIsoString(status.getCurrentTimestamp()) << std::endl;
250 std::cout << " uptime="
251 << time::duration_cast<time::seconds>(status.getCurrentTimestamp()
252 - status.getStartTimestamp()) << std::endl;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700253
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600254 std::cout << " nNameTreeEntries=" << status.getNNameTreeEntries() << std::endl;
255 std::cout << " nFibEntries=" << status.getNFibEntries() << std::endl;
256 std::cout << " nPitEntries=" << status.getNPitEntries() << std::endl;
257 std::cout << " nMeasurementsEntries=" << status.getNMeasurementsEntries() << std::endl;
258 std::cout << " nCsEntries=" << status.getNCsEntries() << std::endl;
259 std::cout << " nInInterests=" << status.getNInInterests() << std::endl;
260 std::cout << " nOutInterests=" << status.getNOutInterests() << std::endl;
261 std::cout << " nInDatas=" << status.getNInDatas() << std::endl;
262 std::cout << " nOutDatas=" << status.getNOutDatas() << std::endl;
263 }
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300264
265 runNextStep();
266 }
267
268 //////////////////////////////////////////////////////////////////////////////////
269 //////////////////////////////////////////////////////////////////////////////////
270
271 void
272 fetchChannelStatusInformation()
273 {
274 m_buffer = make_shared<OBufferStream>();
275
276 Interest interest("/localhost/nfd/faces/channels");
277 interest.setChildSelector(1);
278 interest.setMustBeFresh(true);
279
280 m_face.expressInterest(interest,
281 bind(&NfdStatus::fetchSegments, this, _2,
282 &NfdStatus::afterFetchedChannelStatusInformation),
283 bind(&NfdStatus::onTimeout, this));
jeraldabrahamb6dde382014-03-19 18:58:09 -0700284 }
285
286 void
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300287 afterFetchedChannelStatusInformation()
jeraldabrahamb6dde382014-03-19 18:58:09 -0700288 {
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300289 ConstBufferPtr buf = m_buffer->buf();
Junxiao Shi78926c92015-02-28 22:56:06 -0700290 if (m_isOutputXml) {
291 std::cout << "<channels>";
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300292
Junxiao Shi78926c92015-02-28 22:56:06 -0700293 size_t offset = 0;
294 while (offset < buf->size()) {
295 bool isOk = false;
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300296 Block block;
Junxiao Shi78926c92015-02-28 22:56:06 -0700297 std::tie(isOk, block) = Block::fromBuffer(buf, offset);
298 if (!isOk) {
299 std::cerr << "ERROR: cannot decode ChannelStatus TLV" << std::endl;
300 break;
301 }
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300302
Junxiao Shi78926c92015-02-28 22:56:06 -0700303 offset += block.size();
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300304
Junxiao Shi78926c92015-02-28 22:56:06 -0700305 nfd::ChannelStatus channelStatus(block);
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300306
Junxiao Shi78926c92015-02-28 22:56:06 -0700307 std::cout << "<channel>";
308 std::string localUri(channelStatus.getLocalUri());
309 escapeSpecialCharacters(&localUri);
310 std::cout << "<localUri>" << localUri << "</localUri>";
311 std::cout << "</channel>";
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300312 }
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300313
Junxiao Shi78926c92015-02-28 22:56:06 -0700314 std::cout << "</channels>";
315 }
316 else {
317 std::cout << "Channels:" << std::endl;
318
319 size_t offset = 0;
320 while (offset < buf->size()) {
321 bool isOk = false;
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300322 Block block;
Junxiao Shi78926c92015-02-28 22:56:06 -0700323 std::tie(isOk, block) = Block::fromBuffer(buf, offset);
324 if (!isOk) {
325 std::cerr << "ERROR: cannot decode ChannelStatus TLV" << std::endl;
326 break;
327 }
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300328
Junxiao Shi78926c92015-02-28 22:56:06 -0700329 offset += block.size();
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300330
Junxiao Shi78926c92015-02-28 22:56:06 -0700331 nfd::ChannelStatus channelStatus(block);
332 std::cout << " " << channelStatus.getLocalUri() << std::endl;
333 }
334 }
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300335
336 runNextStep();
337 }
338
339 //////////////////////////////////////////////////////////////////////////////////
340 //////////////////////////////////////////////////////////////////////////////////
341
342 void
343 fetchFaceStatusInformation()
344 {
345 m_buffer = make_shared<OBufferStream>();
346
347 Interest interest("/localhost/nfd/faces/list");
jeraldabrahamb6dde382014-03-19 18:58:09 -0700348 interest.setChildSelector(1);
349 interest.setMustBeFresh(true);
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300350
351 m_face.expressInterest(interest,
352 bind(&NfdStatus::fetchSegments, this, _2,
353 &NfdStatus::afterFetchedFaceStatusInformation),
jeraldabrahamb6dde382014-03-19 18:58:09 -0700354 bind(&NfdStatus::onTimeout, this));
355 }
356
357 void
358 afterFetchedFaceStatusInformation()
359 {
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700360 ConstBufferPtr buf = m_buffer->buf();
Junxiao Shi78926c92015-02-28 22:56:06 -0700361 if (m_isOutputXml) {
362 std::cout << "<faces>";
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600363
Junxiao Shi78926c92015-02-28 22:56:06 -0700364 size_t offset = 0;
365 while (offset < buf->size()) {
366 bool isOk = false;
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600367 Block block;
Junxiao Shi78926c92015-02-28 22:56:06 -0700368 std::tie(isOk, block) = Block::fromBuffer(buf, offset);
369 if (!isOk) {
370 std::cerr << "ERROR: cannot decode FaceStatus TLV" << std::endl;
371 break;
372 }
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600373
Junxiao Shi78926c92015-02-28 22:56:06 -0700374 offset += block.size();
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600375
Junxiao Shi78926c92015-02-28 22:56:06 -0700376 nfd::FaceStatus faceStatus(block);
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600377
Junxiao Shi78926c92015-02-28 22:56:06 -0700378 std::cout << "<face>";
379 std::cout << "<faceId>" << faceStatus.getFaceId() << "</faceId>";
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600380
Junxiao Shi78926c92015-02-28 22:56:06 -0700381 std::string remoteUri(faceStatus.getRemoteUri());
382 escapeSpecialCharacters(&remoteUri);
383 std::cout << "<remoteUri>" << remoteUri << "</remoteUri>";
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600384
Junxiao Shi78926c92015-02-28 22:56:06 -0700385 std::string localUri(faceStatus.getLocalUri());
386 escapeSpecialCharacters(&localUri);
387 std::cout << "<localUri>" << localUri << "</localUri>";
Alexander Afanasyev40c61f72014-06-30 17:21:01 -0700388
Junxiao Shi78926c92015-02-28 22:56:06 -0700389 if (faceStatus.hasExpirationPeriod()) {
390 std::cout << "<expirationPeriod>PT"
391 << time::duration_cast<time::seconds>(faceStatus.getExpirationPeriod())
392 .count() << "S"
393 << "</expirationPeriod>";
394 }
Alexander Afanasyev40c61f72014-06-30 17:21:01 -0700395
Junxiao Shi78926c92015-02-28 22:56:06 -0700396 std::cout << "<faceScope>" << faceStatus.getFaceScope()
397 << "</faceScope>";
398 std::cout << "<facePersistency>" << faceStatus.getFacePersistency()
399 << "</facePersistency>";
400 std::cout << "<linkType>" << faceStatus.getLinkType()
401 << "</linkType>";
Chengyu Fan27d570a2014-10-09 11:52:17 -0600402
Junxiao Shi78926c92015-02-28 22:56:06 -0700403 std::cout << "<packetCounters>";
404 std::cout << "<incomingPackets>";
405 std::cout << "<nInterests>" << faceStatus.getNInInterests()
406 << "</nInterests>";
407 std::cout << "<nDatas>" << faceStatus.getNInDatas()
408 << "</nDatas>";
409 std::cout << "</incomingPackets>";
410 std::cout << "<outgoingPackets>";
411 std::cout << "<nInterests>" << faceStatus.getNOutInterests()
412 << "</nInterests>";
413 std::cout << "<nDatas>" << faceStatus.getNOutDatas()
414 << "</nDatas>";
415 std::cout << "</outgoingPackets>";
416 std::cout << "</packetCounters>";
Alexander Afanasyevd3967a22014-06-30 12:22:10 -0700417
Junxiao Shi78926c92015-02-28 22:56:06 -0700418 std::cout << "<byteCounters>";
419 std::cout << "<incomingBytes>" << faceStatus.getNInBytes()
420 << "</incomingBytes>";
421 std::cout << "<outgoingBytes>" << faceStatus.getNOutBytes()
422 << "</outgoingBytes>";
423 std::cout << "</byteCounters>";
Chengyu Fan3331cfa2014-07-25 17:36:31 -0600424
Junxiao Shi78926c92015-02-28 22:56:06 -0700425 std::cout << "</face>";
jeraldabrahamb6dde382014-03-19 18:58:09 -0700426 }
Junxiao Shi78926c92015-02-28 22:56:06 -0700427 std::cout << "</faces>";
428 }
429 else {
430 std::cout << "Faces:" << std::endl;
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600431
Junxiao Shi78926c92015-02-28 22:56:06 -0700432 size_t offset = 0;
433 while (offset < buf->size()) {
434 bool isOk = false;
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600435 Block block;
Junxiao Shi78926c92015-02-28 22:56:06 -0700436 std::tie(isOk, block) = Block::fromBuffer(buf, offset);
437 if (!isOk) {
438 std::cerr << "ERROR: cannot decode FaceStatus TLV" << std::endl;
439 break;
440 }
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600441
Junxiao Shi78926c92015-02-28 22:56:06 -0700442 offset += block.size();
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600443
Junxiao Shi78926c92015-02-28 22:56:06 -0700444 nfd::FaceStatus faceStatus(block);
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600445
Junxiao Shi78926c92015-02-28 22:56:06 -0700446 std::cout << " faceid=" << faceStatus.getFaceId()
447 << " remote=" << faceStatus.getRemoteUri()
448 << " local=" << faceStatus.getLocalUri();
449 if (faceStatus.hasExpirationPeriod()) {
450 std::cout << " expires="
451 << time::duration_cast<time::seconds>(faceStatus.getExpirationPeriod())
452 .count() << "s";
453 }
454 std::cout << " counters={"
455 << "in={" << faceStatus.getNInInterests() << "i "
456 << faceStatus.getNInDatas() << "d "
457 << faceStatus.getNInBytes() << "B}"
458 << " out={" << faceStatus.getNOutInterests() << "i "
459 << faceStatus.getNOutDatas() << "d "
460 << faceStatus.getNOutBytes() << "B}"
461 << "}";
462 std::cout << " " << faceStatus.getFaceScope()
463 << " " << faceStatus.getFacePersistency()
464 << " " << faceStatus.getLinkType();
465 std::cout << std::endl;
466 }
467 }
jeraldabrahamb6dde382014-03-19 18:58:09 -0700468
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300469 runNextStep();
jeraldabrahamb6dde382014-03-19 18:58:09 -0700470 }
471
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300472 //////////////////////////////////////////////////////////////////////////////////
473 //////////////////////////////////////////////////////////////////////////////////
474
jeraldabrahamb6dde382014-03-19 18:58:09 -0700475 void
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300476 fetchFibEnumerationInformation()
jeraldabrahamb6dde382014-03-19 18:58:09 -0700477 {
478 m_buffer = make_shared<OBufferStream>();
479
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300480 Interest interest("/localhost/nfd/fib/list");
jeraldabrahamb6dde382014-03-19 18:58:09 -0700481 interest.setChildSelector(1);
482 interest.setMustBeFresh(true);
jeraldabrahamb6dde382014-03-19 18:58:09 -0700483 m_face.expressInterest(interest,
484 bind(&NfdStatus::fetchSegments, this, _2,
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300485 &NfdStatus::afterFetchedFibEnumerationInformation),
jeraldabrahamb6dde382014-03-19 18:58:09 -0700486 bind(&NfdStatus::onTimeout, this));
487 }
488
489 void
490 afterFetchedFibEnumerationInformation()
491 {
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700492 ConstBufferPtr buf = m_buffer->buf();
Junxiao Shi78926c92015-02-28 22:56:06 -0700493 if (m_isOutputXml) {
494 std::cout << "<fib>";
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700495
Junxiao Shi78926c92015-02-28 22:56:06 -0700496 size_t offset = 0;
497 while (offset < buf->size()) {
498 bool isOk = false;
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600499 Block block;
Junxiao Shi78926c92015-02-28 22:56:06 -0700500 std::tie(isOk, block) = Block::fromBuffer(buf, offset);
501 if (!isOk) {
502 std::cerr << "ERROR: cannot decode FibEntry TLV";
503 break;
504 }
505 offset += block.size();
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600506
Junxiao Shi78926c92015-02-28 22:56:06 -0700507 nfd::FibEntry fibEntry(block);
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600508
Junxiao Shi78926c92015-02-28 22:56:06 -0700509 std::cout << "<fibEntry>";
510 std::string prefix(fibEntry.getPrefix().toUri());
511 escapeSpecialCharacters(&prefix);
512 std::cout << "<prefix>" << prefix << "</prefix>";
513 std::cout << "<nextHops>";
514 for (const nfd::NextHopRecord& nextHop : fibEntry.getNextHopRecords()) {
515 std::cout << "<nextHop>" ;
516 std::cout << "<faceId>" << nextHop.getFaceId() << "</faceId>";
517 std::cout << "<cost>" << nextHop.getCost() << "</cost>";
518 std::cout << "</nextHop>";
519 }
520 std::cout << "</nextHops>";
521 std::cout << "</fibEntry>";
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600522 }
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600523
Junxiao Shi78926c92015-02-28 22:56:06 -0700524 std::cout << "</fib>";
525 }
526 else {
527 std::cout << "FIB:" << std::endl;
528
529 size_t offset = 0;
530 while (offset < buf->size()) {
531 bool isOk = false;
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600532 Block block;
Junxiao Shi78926c92015-02-28 22:56:06 -0700533 std::tie(isOk, block) = Block::fromBuffer(buf, offset);
534 if (!isOk) {
535 std::cerr << "ERROR: cannot decode FibEntry TLV" << std::endl;
536 break;
537 }
538 offset += block.size();
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600539
Junxiao Shi78926c92015-02-28 22:56:06 -0700540 nfd::FibEntry fibEntry(block);
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600541
Junxiao Shi78926c92015-02-28 22:56:06 -0700542 std::cout << " " << fibEntry.getPrefix() << " nexthops={";
543 bool isFirst = true;
544 for (const nfd::NextHopRecord& nextHop : fibEntry.getNextHopRecords()) {
545 if (isFirst)
546 isFirst = false;
547 else
548 std::cout << ", ";
549
550 std::cout << "faceid=" << nextHop.getFaceId()
551 << " (cost=" << nextHop.getCost() << ")";
552 }
553 std::cout << "}" << std::endl;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700554 }
Junxiao Shi78926c92015-02-28 22:56:06 -0700555 }
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300556
557 runNextStep();
jeraldabrahamb6dde382014-03-19 18:58:09 -0700558 }
559
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300560 //////////////////////////////////////////////////////////////////////////////////
561 //////////////////////////////////////////////////////////////////////////////////
562
jeraldabrahamb6dde382014-03-19 18:58:09 -0700563 void
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300564 fetchStrategyChoiceInformation()
jeraldabrahamb6dde382014-03-19 18:58:09 -0700565 {
566 m_buffer = make_shared<OBufferStream>();
567
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300568 Interest interest("/localhost/nfd/strategy-choice/list");
jeraldabrahamb6dde382014-03-19 18:58:09 -0700569 interest.setChildSelector(1);
570 interest.setMustBeFresh(true);
571 m_face.expressInterest(interest,
572 bind(&NfdStatus::fetchSegments, this, _2,
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300573 &NfdStatus::afterFetchedStrategyChoiceInformationInformation),
jeraldabrahamb6dde382014-03-19 18:58:09 -0700574 bind(&NfdStatus::onTimeout, this));
575 }
576
577 void
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300578 afterFetchedStrategyChoiceInformationInformation()
579 {
580 ConstBufferPtr buf = m_buffer->buf();
Junxiao Shi78926c92015-02-28 22:56:06 -0700581 if (m_isOutputXml) {
582 std::cout << "<strategyChoices>";
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300583
Junxiao Shi78926c92015-02-28 22:56:06 -0700584 size_t offset = 0;
585 while (offset < buf->size()) {
586 bool isOk = false;
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300587 Block block;
Junxiao Shi78926c92015-02-28 22:56:06 -0700588 std::tie(isOk, block) = Block::fromBuffer(buf, offset);
589 if (!isOk) {
590 std::cerr << "ERROR: cannot decode StrategyChoice TLV";
591 break;
592 }
593 offset += block.size();
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300594
Junxiao Shi78926c92015-02-28 22:56:06 -0700595 nfd::StrategyChoice strategyChoice(block);
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300596
Junxiao Shi78926c92015-02-28 22:56:06 -0700597 std::cout << "<strategyChoice>";
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300598
Junxiao Shi78926c92015-02-28 22:56:06 -0700599 std::string name(strategyChoice.getName().toUri());
600 escapeSpecialCharacters(&name);
601 std::cout << "<namespace>" << name << "</namespace>";
602 std::cout << "<strategy>";
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300603
Junxiao Shi78926c92015-02-28 22:56:06 -0700604 std::string strategy(strategyChoice.getStrategy().toUri());
605 escapeSpecialCharacters(&strategy);
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300606
Junxiao Shi78926c92015-02-28 22:56:06 -0700607 std::cout << "<name>" << strategy << "</name>";
608 std::cout << "</strategy>";
609 std::cout << "</strategyChoice>";
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300610 }
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300611
Junxiao Shi78926c92015-02-28 22:56:06 -0700612 std::cout << "</strategyChoices>";
613 }
614 else {
615 std::cout << "Strategy choices:" << std::endl;
616
617 size_t offset = 0;
618 while (offset < buf->size()) {
619 bool isOk = false;
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300620 Block block;
Junxiao Shi78926c92015-02-28 22:56:06 -0700621 std::tie(isOk, block) = Block::fromBuffer(buf, offset);
622 if (!isOk) {
623 std::cerr << "ERROR: cannot decode StrategyChoice TLV" << std::endl;
624 break;
625 }
626 offset += block.size();
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300627
Junxiao Shi78926c92015-02-28 22:56:06 -0700628 nfd::StrategyChoice strategyChoice(block);
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300629
Junxiao Shi78926c92015-02-28 22:56:06 -0700630 std::cout << " " << strategyChoice.getName()
631 << " strategy=" << strategyChoice.getStrategy() << std::endl;
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300632 }
Junxiao Shi78926c92015-02-28 22:56:06 -0700633 }
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300634
635 runNextStep();
636 }
637
638 void
Chengyu Fan30aa2072014-07-20 13:52:32 -0600639 fetchRibStatusInformation()
640 {
641 m_buffer = make_shared<OBufferStream>();
642
643 Interest interest("/localhost/nfd/rib/list");
644 interest.setChildSelector(1);
645 interest.setMustBeFresh(true);
646
647 m_face.expressInterest(interest,
648 bind(&NfdStatus::fetchSegments, this, _2,
649 &NfdStatus::afterFetchedRibStatusInformation),
650 bind(&NfdStatus::onTimeout, this));
651 }
652
653 void
654 afterFetchedRibStatusInformation()
655 {
656 ConstBufferPtr buf = m_buffer->buf();
Junxiao Shi78926c92015-02-28 22:56:06 -0700657 if (m_isOutputXml) {
658 std::cout << "<rib>";
Chengyu Fan30aa2072014-07-20 13:52:32 -0600659
Junxiao Shi78926c92015-02-28 22:56:06 -0700660 size_t offset = 0;
661 while (offset < buf->size()) {
662 bool isOk = false;
Chengyu Fan30aa2072014-07-20 13:52:32 -0600663 Block block;
Junxiao Shi78926c92015-02-28 22:56:06 -0700664 std::tie(isOk, block) = Block::fromBuffer(buf, offset);
665 if (!isOk) {
666 std::cerr << "ERROR: cannot decode RibEntry TLV";
667 break;
668 }
669 offset += block.size();
Chengyu Fan30aa2072014-07-20 13:52:32 -0600670
Junxiao Shi78926c92015-02-28 22:56:06 -0700671 nfd::RibEntry ribEntry(block);
Chengyu Fan30aa2072014-07-20 13:52:32 -0600672
Junxiao Shi78926c92015-02-28 22:56:06 -0700673 std::cout << "<ribEntry>";
674 std::string prefix(ribEntry.getName().toUri());
675 escapeSpecialCharacters(&prefix);
676 std::cout << "<prefix>" << prefix << "</prefix>";
677 std::cout << "<routes>";
678 for (const nfd::Route& nextRoute : ribEntry) {
679 std::cout << "<route>" ;
680 std::cout << "<faceId>" << nextRoute.getFaceId() << "</faceId>";
681 std::cout << "<origin>" << nextRoute.getOrigin() << "</origin>";
682 std::cout << "<cost>" << nextRoute.getCost() << "</cost>";
Chengyu Fan1c630ba2014-08-20 13:27:58 -0500683
Junxiao Shi78926c92015-02-28 22:56:06 -0700684 std::cout << "<flags>";
685 if (nextRoute.isChildInherit())
686 std::cout << "<childInherit/>";
687 if (nextRoute.isRibCapture())
688 std::cout << "<ribCapture/>";
689 std::cout << "</flags>";
Chengyu Fan1c630ba2014-08-20 13:27:58 -0500690
Junxiao Shi78926c92015-02-28 22:56:06 -0700691 if (!nextRoute.hasInfiniteExpirationPeriod()) {
692 std::cout << "<expirationPeriod>PT"
693 << time::duration_cast<time::seconds>(nextRoute.getExpirationPeriod())
694 .count() << "S"
695 << "</expirationPeriod>";
Chengyu Fan30aa2072014-07-20 13:52:32 -0600696 }
Junxiao Shi78926c92015-02-28 22:56:06 -0700697 std::cout << "</route>";
698 }
699 std::cout << "</routes>";
700 std::cout << "</ribEntry>";
Chengyu Fan30aa2072014-07-20 13:52:32 -0600701 }
Chengyu Fan30aa2072014-07-20 13:52:32 -0600702
Junxiao Shi78926c92015-02-28 22:56:06 -0700703 std::cout << "</rib>";
704 }
705 else {
706 std::cout << "RIB:" << std::endl;
707
708 size_t offset = 0;
709 while (offset < buf->size()) {
710 bool isOk = false;
Chengyu Fan30aa2072014-07-20 13:52:32 -0600711 Block block;
Junxiao Shi78926c92015-02-28 22:56:06 -0700712 std::tie(isOk, block) = Block::fromBuffer(buf, offset);
713 if (!isOk) {
714 std::cerr << "ERROR: cannot decode RibEntry TLV" << std::endl;
715 break;
716 }
Chengyu Fan30aa2072014-07-20 13:52:32 -0600717
Junxiao Shi78926c92015-02-28 22:56:06 -0700718 offset += block.size();
Chengyu Fan30aa2072014-07-20 13:52:32 -0600719
Junxiao Shi78926c92015-02-28 22:56:06 -0700720 nfd::RibEntry ribEntry(block);
Chengyu Fan30aa2072014-07-20 13:52:32 -0600721
Junxiao Shi78926c92015-02-28 22:56:06 -0700722 std::cout << " " << ribEntry.getName().toUri() << " route={";
723 bool isFirst = true;
724 for (const nfd::Route& nextRoute : ribEntry) {
725 if (isFirst)
726 isFirst = false;
727 else
728 std::cout << ", ";
Chengyu Fan1c630ba2014-08-20 13:27:58 -0500729
Junxiao Shi78926c92015-02-28 22:56:06 -0700730 std::cout << "faceid=" << nextRoute.getFaceId()
731 << " (origin=" << nextRoute.getOrigin()
732 << " cost=" << nextRoute.getCost();
733 if (!nextRoute.hasInfiniteExpirationPeriod()) {
734 std::cout << " expires="
735 << time::duration_cast<time::seconds>(nextRoute.getExpirationPeriod())
736 .count() << "s";
Chengyu Fan30aa2072014-07-20 13:52:32 -0600737 }
Junxiao Shi78926c92015-02-28 22:56:06 -0700738
739 if (nextRoute.isChildInherit())
740 std::cout << " ChildInherit";
741 if (nextRoute.isRibCapture())
742 std::cout << " RibCapture";
743
744 std::cout << ")";
745 }
746 std::cout << "}" << std::endl;
747 }
748 }
Chengyu Fan30aa2072014-07-20 13:52:32 -0600749
750 runNextStep();
751 }
752
753
754 void
jeraldabrahamb6dde382014-03-19 18:58:09 -0700755 fetchInformation()
756 {
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300757 if (m_isOutputXml ||
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600758 (!m_needVersionRetrieval &&
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300759 !m_needChannelStatusRetrieval &&
760 !m_needFaceStatusRetrieval &&
761 !m_needFibEnumerationRetrieval &&
Chengyu Fan30aa2072014-07-20 13:52:32 -0600762 !m_needRibStatusRetrieval &&
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300763 !m_needStrategyChoiceRetrieval))
jeraldabrahamb6dde382014-03-19 18:58:09 -0700764 {
765 enableVersionRetrieval();
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300766 enableChannelStatusRetrieval();
jeraldabrahamb6dde382014-03-19 18:58:09 -0700767 enableFaceStatusRetrieval();
768 enableFibEnumerationRetrieval();
Chengyu Fan30aa2072014-07-20 13:52:32 -0600769 enableRibStatusRetrieval();
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300770 enableStrategyChoiceRetrieval();
jeraldabrahamb6dde382014-03-19 18:58:09 -0700771 }
772
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300773 if (m_isOutputXml)
774 m_fetchSteps.push_back(bind(&NfdStatus::printXmlHeader, this));
775
jeraldabrahamb6dde382014-03-19 18:58:09 -0700776 if (m_needVersionRetrieval)
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300777 m_fetchSteps.push_back(bind(&NfdStatus::fetchVersionInformation, this));
jeraldabrahamb6dde382014-03-19 18:58:09 -0700778
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300779 if (m_needChannelStatusRetrieval)
780 m_fetchSteps.push_back(bind(&NfdStatus::fetchChannelStatusInformation, this));
781
782 if (m_needFaceStatusRetrieval)
783 m_fetchSteps.push_back(bind(&NfdStatus::fetchFaceStatusInformation, this));
784
785 if (m_needFibEnumerationRetrieval)
786 m_fetchSteps.push_back(bind(&NfdStatus::fetchFibEnumerationInformation, this));
787
Chengyu Fan30aa2072014-07-20 13:52:32 -0600788 if (m_needRibStatusRetrieval)
789 m_fetchSteps.push_back(bind(&NfdStatus::fetchRibStatusInformation, this));
790
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300791 if (m_needStrategyChoiceRetrieval)
792 m_fetchSteps.push_back(bind(&NfdStatus::fetchStrategyChoiceInformation, this));
793
794 if (m_isOutputXml)
795 m_fetchSteps.push_back(bind(&NfdStatus::printXmlFooter, this));
796
797 runNextStep();
jeraldabrahamb6dde382014-03-19 18:58:09 -0700798 m_face.processEvents();
799 }
800
801private:
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300802 void
803 printXmlHeader()
804 {
805 std::cout << "<?xml version=\"1.0\"?>";
806 std::cout << "<nfdStatus xmlns=\"ndn:/localhost/nfd/status/1\">";
807
808 runNextStep();
809 }
810
811 void
812 printXmlFooter()
813 {
814 std::cout << "</nfdStatus>";
815
816 runNextStep();
817 }
818
819 void
820 runNextStep()
821 {
822 if (m_fetchSteps.empty())
823 return;
824
825 function<void()> nextStep = m_fetchSteps.front();
826 m_fetchSteps.pop_front();
827 nextStep();
828 }
829
830private:
jeraldabrahamb6dde382014-03-19 18:58:09 -0700831 std::string m_toolName;
832 bool m_needVersionRetrieval;
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300833 bool m_needChannelStatusRetrieval;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700834 bool m_needFaceStatusRetrieval;
835 bool m_needFibEnumerationRetrieval;
Chengyu Fan30aa2072014-07-20 13:52:32 -0600836 bool m_needRibStatusRetrieval;
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300837 bool m_needStrategyChoiceRetrieval;
838 bool m_isOutputXml;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700839 Face m_face;
840
841 shared_ptr<OBufferStream> m_buffer;
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300842
843 std::deque<function<void()> > m_fetchSteps;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700844};
845
846}
847
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700848int main(int argc, char* argv[])
jeraldabrahamb6dde382014-03-19 18:58:09 -0700849{
850 int option;
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700851 ndn::NfdStatus nfdStatus(argv[0]);
jeraldabrahamb6dde382014-03-19 18:58:09 -0700852
Chengyu Fan30aa2072014-07-20 13:52:32 -0600853 while ((option = getopt(argc, argv, "hvcfbrsxV")) != -1) {
jeraldabrahamb6dde382014-03-19 18:58:09 -0700854 switch (option) {
855 case 'h':
856 nfdStatus.usage();
Alexander Afanasyev60a7ba52014-03-23 11:23:06 -0700857 return 0;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700858 case 'v':
859 nfdStatus.enableVersionRetrieval();
860 break;
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300861 case 'c':
862 nfdStatus.enableChannelStatusRetrieval();
863 break;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700864 case 'f':
865 nfdStatus.enableFaceStatusRetrieval();
866 break;
867 case 'b':
868 nfdStatus.enableFibEnumerationRetrieval();
869 break;
Chengyu Fan30aa2072014-07-20 13:52:32 -0600870 case 'r':
871 nfdStatus.enableRibStatusRetrieval();
872 break;
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300873 case 's':
874 nfdStatus.enableStrategyChoiceRetrieval();
875 break;
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600876 case 'x':
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300877 nfdStatus.enableXmlOutput();
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600878 break;
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700879 case 'V':
880 std::cout << NFD_VERSION_BUILD_STRING << std::endl;
881 return 0;
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700882 default:
jeraldabrahamb6dde382014-03-19 18:58:09 -0700883 nfdStatus.usage();
884 return 1;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700885 }
886 }
887
888 try {
889 nfdStatus.fetchInformation();
890 }
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700891 catch (std::exception& e) {
jeraldabrahamb6dde382014-03-19 18:58:09 -0700892 std::cerr << "ERROR: " << e.what() << std::endl;
893 return 2;
894 }
895
896 return 0;
897}