blob: 5d351082cd4e296823525e94e739f3a22564ab55 [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/**
Alexander Afanasyev4a771362014-04-24 21:29:33 -07003 * Copyright (c) 2014, 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>
39#include <ndn-cxx/management/nfd-strategy-choice.hpp>
jeraldabrahamb6dde382014-03-19 18:58:09 -070040
Alexander Afanasyevb3893c92014-05-15 01:49:54 -070041#include <boost/algorithm/string/replace.hpp>
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +030042#include <list>
Alexander Afanasyevb3893c92014-05-15 01:49:54 -070043
jeraldabrahamb6dde382014-03-19 18:58:09 -070044namespace ndn {
45
46class NfdStatus
47{
48public:
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -070049 explicit
jeraldabrahamb6dde382014-03-19 18:58:09 -070050 NfdStatus(char* toolName)
51 : m_toolName(toolName)
52 , m_needVersionRetrieval(false)
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +030053 , m_needChannelStatusRetrieval(false)
jeraldabrahamb6dde382014-03-19 18:58:09 -070054 , m_needFaceStatusRetrieval(false)
55 , m_needFibEnumerationRetrieval(false)
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +030056 , m_needStrategyChoiceRetrieval(false)
57 , m_isOutputXml(false)
jeraldabrahamb6dde382014-03-19 18:58:09 -070058 {
59 }
60
61 void
62 usage()
63 {
Alexander Afanasyev60a7ba52014-03-23 11:23:06 -070064 std::cout << "Usage: \n " << m_toolName << " [options]\n\n"
65 "Show NFD version and status information\n\n"
66 "Options:\n"
67 " [-h] - print this help message\n"
jeraldabrahamb6dde382014-03-19 18:58:09 -070068 " [-v] - retrieve version information\n"
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +030069 " [-c] - retrieve channel status information\n"
jeraldabrahamb6dde382014-03-19 18:58:09 -070070 " [-f] - retrieve face status information\n"
Alexander Afanasyevb47d5382014-05-05 14:35:03 -070071 " [-b] - retrieve FIB information\n"
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +030072 " [-s] - retrieve configured strategy choice for NDN namespaces\n"
Chengyu Fanee92fc72014-06-21 14:58:19 -060073 " [-x] - output NFD status information in XML format\n"
Alexander Afanasyevb47d5382014-05-05 14:35:03 -070074 "\n"
75 " [-V] - show version information of nfd-status and exit\n"
76 "\n"
Alexander Afanasyev60a7ba52014-03-23 11:23:06 -070077 "If no options are provided, all information is retrieved.\n"
Chengyu Fanee92fc72014-06-21 14:58:19 -060078 "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 -070079 ;
jeraldabrahamb6dde382014-03-19 18:58:09 -070080 }
81
82 void
83 enableVersionRetrieval()
84 {
85 m_needVersionRetrieval = true;
86 }
87
88 void
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +030089 enableChannelStatusRetrieval()
90 {
91 m_needChannelStatusRetrieval = true;
92 }
93
94 void
jeraldabrahamb6dde382014-03-19 18:58:09 -070095 enableFaceStatusRetrieval()
96 {
97 m_needFaceStatusRetrieval = true;
98 }
99
100 void
101 enableFibEnumerationRetrieval()
102 {
103 m_needFibEnumerationRetrieval = true;
104 }
105
106 void
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300107 enableStrategyChoiceRetrieval()
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600108 {
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300109 m_needStrategyChoiceRetrieval = true;
110 }
111
112 void
113 enableXmlOutput()
114 {
115 m_isOutputXml = true;
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600116 }
117
118 void
jeraldabrahamb6dde382014-03-19 18:58:09 -0700119 onTimeout()
120 {
121 std::cerr << "Request timed out" << std::endl;
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300122
123 runNextStep();
jeraldabrahamb6dde382014-03-19 18:58:09 -0700124 }
125
126 void
127 fetchSegments(const Data& data, void (NfdStatus::*onDone)())
128 {
129 m_buffer->write((const char*)data.getContent().value(),
130 data.getContent().value_size());
131
132 uint64_t currentSegment = data.getName().get(-1).toSegment();
133
134 const name::Component& finalBlockId = data.getMetaInfo().getFinalBlockId();
135 if (finalBlockId.empty() ||
136 finalBlockId.toSegment() > currentSegment)
137 {
138 m_face.expressInterest(data.getName().getPrefix(-1).appendSegment(currentSegment+1),
139 bind(&NfdStatus::fetchSegments, this, _2, onDone),
140 bind(&NfdStatus::onTimeout, this));
141 }
142 else
143 {
144 return (this->*onDone)();
145 }
146 }
147
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300148 void
149 escapeSpecialCharacters(std::string *data)
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600150 {
151 using boost::algorithm::replace_all;
152 replace_all(*data, "&", "&amp;");
153 replace_all(*data, "\"", "&quot;");
154 replace_all(*data, "\'", "&apos;");
155 replace_all(*data, "<", "&lt;");
156 replace_all(*data, ">", "&gt;");
157 }
158
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300159 //////////////////////////////////////////////////////////////////////////////////
160 //////////////////////////////////////////////////////////////////////////////////
161
162 void
163 fetchVersionInformation()
164 {
165 Interest interest("/localhost/nfd/status");
166 interest.setChildSelector(1);
167 interest.setMustBeFresh(true);
168 m_face.expressInterest(
169 interest,
170 bind(&NfdStatus::afterFetchedVersionInformation, this, _2),
171 bind(&NfdStatus::onTimeout, this));
172 }
173
jeraldabrahamb6dde382014-03-19 18:58:09 -0700174 void
175 afterFetchedVersionInformation(const Data& data)
176 {
Junxiao Shi88d69372014-03-28 11:52:39 -0700177 nfd::ForwarderStatus status(data.getContent());
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300178 if (m_isOutputXml)
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600179 {
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600180 std::cout << "<generalStatus>";
181 std::cout << "<version>"
182 << status.getNfdVersion() << "</version>";
183 std::cout << "<startTime>"
184 << time::toString(status.getStartTimestamp(), "%Y-%m-%dT%H:%M:%S%F")
185 << "</startTime>";
186 std::cout << "<currentTime>"
187 << time::toString(status.getCurrentTimestamp(), "%Y-%m-%dT%H:%M:%S%F")
188 << "</currentTime>";
189 std::cout << "<uptime>PT"
190 << time::duration_cast<time::seconds>(status.getCurrentTimestamp()
191 - status.getStartTimestamp()).count()
192 << "S</uptime>";
193 std::cout << "<nNameTreeEntries>" << status.getNNameTreeEntries()
194 << "</nNameTreeEntries>";
195 std::cout << "<nFibEntries>" << status.getNFibEntries()
196 << "</nFibEntries>";
197 std::cout << "<nPitEntries>" << status.getNPitEntries()
198 << "</nPitEntries>";
199 std::cout << "<nMeasurementsEntries>" << status.getNMeasurementsEntries()
200 << "</nMeasurementsEntries>";
201 std::cout << "<nCsEntries>" << status.getNCsEntries()
202 << "</nCsEntries>";
203 std::cout << "<packetCounters>";
204 std::cout << "<incomingPackets>";
205 std::cout << "<nInterests>" << status.getNInInterests()
206 << "</nInterests>";
207 std::cout << "<nDatas>" << status.getNInDatas()
208 << "</nDatas>";
209 std::cout << "</incomingPackets>";
210 std::cout << "<outgoingPackets>";
211 std::cout << "<nInterests>" << status.getNOutInterests()
212 << "</nInterests>";
213 std::cout << "<nDatas>" << status.getNOutDatas()
214 << "</nDatas>";
215 std::cout << "</outgoingPackets>";
216 std::cout << "</packetCounters>";
217 std::cout << "</generalStatus>";
218 }
219 else
220 {
221 std::cout << "General NFD status:" << std::endl;
222 std::cout << " version="
223 << status.getNfdVersion() << std::endl;
224 std::cout << " startTime="
225 << time::toIsoString(status.getStartTimestamp()) << std::endl;
226 std::cout << " currentTime="
227 << time::toIsoString(status.getCurrentTimestamp()) << std::endl;
228 std::cout << " uptime="
229 << time::duration_cast<time::seconds>(status.getCurrentTimestamp()
230 - status.getStartTimestamp()) << std::endl;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700231
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600232 std::cout << " nNameTreeEntries=" << status.getNNameTreeEntries() << std::endl;
233 std::cout << " nFibEntries=" << status.getNFibEntries() << std::endl;
234 std::cout << " nPitEntries=" << status.getNPitEntries() << std::endl;
235 std::cout << " nMeasurementsEntries=" << status.getNMeasurementsEntries() << std::endl;
236 std::cout << " nCsEntries=" << status.getNCsEntries() << std::endl;
237 std::cout << " nInInterests=" << status.getNInInterests() << std::endl;
238 std::cout << " nOutInterests=" << status.getNOutInterests() << std::endl;
239 std::cout << " nInDatas=" << status.getNInDatas() << std::endl;
240 std::cout << " nOutDatas=" << status.getNOutDatas() << std::endl;
241 }
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300242
243 runNextStep();
244 }
245
246 //////////////////////////////////////////////////////////////////////////////////
247 //////////////////////////////////////////////////////////////////////////////////
248
249 void
250 fetchChannelStatusInformation()
251 {
252 m_buffer = make_shared<OBufferStream>();
253
254 Interest interest("/localhost/nfd/faces/channels");
255 interest.setChildSelector(1);
256 interest.setMustBeFresh(true);
257
258 m_face.expressInterest(interest,
259 bind(&NfdStatus::fetchSegments, this, _2,
260 &NfdStatus::afterFetchedChannelStatusInformation),
261 bind(&NfdStatus::onTimeout, this));
jeraldabrahamb6dde382014-03-19 18:58:09 -0700262 }
263
264 void
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300265 afterFetchedChannelStatusInformation()
jeraldabrahamb6dde382014-03-19 18:58:09 -0700266 {
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300267 ConstBufferPtr buf = m_buffer->buf();
268 if (m_isOutputXml)
269 {
270 std::cout << "<channels>";
271
272 Block block;
273 size_t offset = 0;
274 while (offset < buf->size())
275 {
276 bool ok = Block::fromBuffer(buf, offset, block);
277 if (!ok)
278 {
279 std::cerr << "ERROR: cannot decode ChannelStatus TLV" << std::endl;
280 break;
281 }
282
283 offset += block.size();
284
285 nfd::ChannelStatus channelStatus(block);
286
287 std::cout << "<channel>";
288
289 std::string localUri(channelStatus.getLocalUri());
290 escapeSpecialCharacters(&localUri);
291 std::cout << "<localUri>" << localUri << "</localUri>";
292 std::cout << "</channel>";
293 }
294 std::cout << "</channels>";
295 }
296 else
297 {
298 std::cout << "Channels:" << std::endl;
299
300 Block block;
301 size_t offset = 0;
302 while (offset < buf->size())
303 {
304 bool ok = Block::fromBuffer(buf, offset, block);
305 if (!ok)
306 {
307 std::cerr << "ERROR: cannot decode ChannelStatus TLV" << std::endl;
308 break;
309 }
310
311 offset += block.size();
312
313 nfd::ChannelStatus channelStatus(block);
314 std::cout << " " << channelStatus.getLocalUri() << std::endl;
315 }
316 }
317
318 runNextStep();
319 }
320
321 //////////////////////////////////////////////////////////////////////////////////
322 //////////////////////////////////////////////////////////////////////////////////
323
324 void
325 fetchFaceStatusInformation()
326 {
327 m_buffer = make_shared<OBufferStream>();
328
329 Interest interest("/localhost/nfd/faces/list");
jeraldabrahamb6dde382014-03-19 18:58:09 -0700330 interest.setChildSelector(1);
331 interest.setMustBeFresh(true);
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300332
333 m_face.expressInterest(interest,
334 bind(&NfdStatus::fetchSegments, this, _2,
335 &NfdStatus::afterFetchedFaceStatusInformation),
jeraldabrahamb6dde382014-03-19 18:58:09 -0700336 bind(&NfdStatus::onTimeout, this));
337 }
338
339 void
340 afterFetchedFaceStatusInformation()
341 {
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700342 ConstBufferPtr buf = m_buffer->buf();
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300343 if (m_isOutputXml)
jeraldabrahamb6dde382014-03-19 18:58:09 -0700344 {
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600345 std::cout << "<faces>";
346
347 Block block;
348 size_t offset = 0;
349 while (offset < buf->size())
jeraldabrahamb6dde382014-03-19 18:58:09 -0700350 {
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600351 bool ok = Block::fromBuffer(buf, offset, block);
352 if (!ok)
353 {
354 std::cerr << "ERROR: cannot decode FaceStatus TLV" << std::endl;
355 break;
356 }
357
358 offset += block.size();
359
360 nfd::FaceStatus faceStatus(block);
361
362 std::cout << "<face>";
363 std::cout << "<faceId>" << faceStatus.getFaceId() << "</faceId>";
364
365 std::string remoteUri(faceStatus.getRemoteUri());
366 escapeSpecialCharacters(&remoteUri);
367 std::cout << "<remoteUri>" << remoteUri << "</remoteUri>";
368
369 std::string localUri(faceStatus.getLocalUri());
370 escapeSpecialCharacters(&localUri);
371 std::cout << "<localUri>" << localUri << "</localUri>";
372 std::cout << "<packetCounters>";
373 std::cout << "<incomingPackets>";
374 std::cout << "<nInterests>" << faceStatus.getNInInterests()
375 << "</nInterests>";
376 std::cout << "<nDatas>" << faceStatus.getNInInterests()
377 << "</nDatas>";
378 std::cout << "</incomingPackets>";
379 std::cout << "<outgoingPackets>";
380 std::cout << "<nInterests>" << faceStatus.getNOutInterests()
381 << "</nInterests>";
382 std::cout << "<nDatas>" << faceStatus.getNOutInterests()
383 << "</nDatas>";
384 std::cout << "</outgoingPackets>";
385 std::cout << "</packetCounters>";
Alexander Afanasyevd3967a22014-06-30 12:22:10 -0700386
387 if (faceStatus.getFlags() != 0) {
388 std::cout << "<flags>";
389 if (faceStatus.isLocal()) {
390 std::cout << "<local/>";
391 }
392 if (faceStatus.isOnDemand()) {
393 std::cout << "<on-demand/>";
394 }
395 std::cout << "</flags>";
396 }
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600397 std::cout << "</face>";
jeraldabrahamb6dde382014-03-19 18:58:09 -0700398 }
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600399 std::cout << "</faces>";
jeraldabrahamb6dde382014-03-19 18:58:09 -0700400 }
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600401 else
402 {
403 std::cout << "Faces:" << std::endl;
404
405 Block block;
406 size_t offset = 0;
407 while (offset < buf->size())
408 {
409 bool ok = Block::fromBuffer(buf, offset, block);
410 if (!ok)
411 {
412 std::cerr << "ERROR: cannot decode FaceStatus TLV" << std::endl;
413 break;
414 }
415
416 offset += block.size();
417
418 nfd::FaceStatus faceStatus(block);
419
420 std::cout << " faceid=" << faceStatus.getFaceId()
421 << " remote=" << faceStatus.getRemoteUri()
422 << " local=" << faceStatus.getLocalUri()
423 << " counters={"
424 << "in={" << faceStatus.getNInInterests() << "i "
425 << faceStatus.getNInDatas() << "d}"
426 << " out={" << faceStatus.getNOutInterests() << "i "
427 << faceStatus.getNOutDatas() << "d}"
Alexander Afanasyevd3967a22014-06-30 12:22:10 -0700428 << "}";
429 if (faceStatus.isLocal())
430 std::cout << " local";
431 if (faceStatus.isOnDemand())
432 std::cout << " on-demand";
433 std::cout << std::endl;
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600434 }
435 }
jeraldabrahamb6dde382014-03-19 18:58:09 -0700436
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300437 runNextStep();
jeraldabrahamb6dde382014-03-19 18:58:09 -0700438 }
439
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300440 //////////////////////////////////////////////////////////////////////////////////
441 //////////////////////////////////////////////////////////////////////////////////
442
jeraldabrahamb6dde382014-03-19 18:58:09 -0700443 void
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300444 fetchFibEnumerationInformation()
jeraldabrahamb6dde382014-03-19 18:58:09 -0700445 {
446 m_buffer = make_shared<OBufferStream>();
447
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300448 Interest interest("/localhost/nfd/fib/list");
jeraldabrahamb6dde382014-03-19 18:58:09 -0700449 interest.setChildSelector(1);
450 interest.setMustBeFresh(true);
jeraldabrahamb6dde382014-03-19 18:58:09 -0700451 m_face.expressInterest(interest,
452 bind(&NfdStatus::fetchSegments, this, _2,
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300453 &NfdStatus::afterFetchedFibEnumerationInformation),
jeraldabrahamb6dde382014-03-19 18:58:09 -0700454 bind(&NfdStatus::onTimeout, this));
455 }
456
457 void
458 afterFetchedFibEnumerationInformation()
459 {
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700460 ConstBufferPtr buf = m_buffer->buf();
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300461 if (m_isOutputXml)
jeraldabrahamb6dde382014-03-19 18:58:09 -0700462 {
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600463 std::cout << "<fib>";
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700464
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600465 Block block;
466 size_t offset = 0;
467 while (offset < buf->size())
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700468 {
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600469 bool ok = Block::fromBuffer(buf, offset, block);
470 if (!ok)
471 {
472 std::cerr << "ERROR: cannot decode FibEntry TLV";
473 break;
474 }
475 offset += block.size();
476
477 nfd::FibEntry fibEntry(block);
478
479 std::cout << "<fibEntry>";
480 std::string prefix(fibEntry.getPrefix().toUri());
481 escapeSpecialCharacters(&prefix);
482 std::cout << "<prefix>" << prefix << "</prefix>";
483 std::cout << "<nextHops>";
484 for (std::list<nfd::NextHopRecord>::const_iterator
485 nextHop = fibEntry.getNextHopRecords().begin();
486 nextHop != fibEntry.getNextHopRecords().end();
487 ++nextHop)
488 {
489 std::cout << "<nextHop>" ;
490 std::cout << "<faceId>" << nextHop->getFaceId() << "</faceId>";
491 std::cout << "<cost>" << nextHop->getCost() << "</cost>";
492 std::cout << "</nextHop>";
493 }
494 std::cout << "</nextHops>";
495 std::cout << "</fibEntry>";
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700496 }
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600497
498 std::cout << "</fib>";
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600499 }
500 else
501 {
502 std::cout << "FIB:" << std::endl;
503
504 Block block;
505 size_t offset = 0;
506 while (offset < buf->size())
507 {
508 bool ok = Block::fromBuffer(buf, offset, block);
509 if (!ok)
510 {
511 std::cerr << "ERROR: cannot decode FibEntry TLV" << std::endl;
512 break;
513 }
514 offset += block.size();
515
516 nfd::FibEntry fibEntry(block);
517
518 std::cout << " " << fibEntry.getPrefix() << " nexthops={";
519 for (std::list<nfd::NextHopRecord>::const_iterator
520 nextHop = fibEntry.getNextHopRecords().begin();
521 nextHop != fibEntry.getNextHopRecords().end();
522 ++nextHop)
523 {
524 if (nextHop != fibEntry.getNextHopRecords().begin())
525 std::cout << ", ";
526 std::cout << "faceid=" << nextHop->getFaceId()
527 << " (cost=" << nextHop->getCost() << ")";
528 }
529 std::cout << "}" << std::endl;
530 }
jeraldabrahamb6dde382014-03-19 18:58:09 -0700531 }
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300532
533 runNextStep();
jeraldabrahamb6dde382014-03-19 18:58:09 -0700534 }
535
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300536 //////////////////////////////////////////////////////////////////////////////////
537 //////////////////////////////////////////////////////////////////////////////////
538
jeraldabrahamb6dde382014-03-19 18:58:09 -0700539 void
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300540 fetchStrategyChoiceInformation()
jeraldabrahamb6dde382014-03-19 18:58:09 -0700541 {
542 m_buffer = make_shared<OBufferStream>();
543
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300544 Interest interest("/localhost/nfd/strategy-choice/list");
jeraldabrahamb6dde382014-03-19 18:58:09 -0700545 interest.setChildSelector(1);
546 interest.setMustBeFresh(true);
547 m_face.expressInterest(interest,
548 bind(&NfdStatus::fetchSegments, this, _2,
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300549 &NfdStatus::afterFetchedStrategyChoiceInformationInformation),
jeraldabrahamb6dde382014-03-19 18:58:09 -0700550 bind(&NfdStatus::onTimeout, this));
551 }
552
553 void
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300554 afterFetchedStrategyChoiceInformationInformation()
555 {
556 ConstBufferPtr buf = m_buffer->buf();
557 if (m_isOutputXml)
558 {
559 std::cout << "<strategyChoices>";
560
561 Block block;
562 size_t offset = 0;
563 while (offset < buf->size())
564 {
565 bool ok = Block::fromBuffer(buf, offset, block);
566 if (!ok)
567 {
568 std::cerr << "ERROR: cannot decode StrategyChoice TLV";
569 break;
570 }
571 offset += block.size();
572
573 nfd::StrategyChoice strategyChoice(block);
574
575 std::cout << "<strategyChoice>";
576
577 std::string name(strategyChoice.getName().toUri());
578 escapeSpecialCharacters(&name);
579 std::cout << "<namespace>" << name << "</namespace>";
580 std::cout << "<strategy>";
581
582 std::string strategy(strategyChoice.getStrategy().toUri());
583 escapeSpecialCharacters(&strategy);
584
585 std::cout << "<name>" << strategy << "</name>";
586 std::cout << "</strategy>";
587 std::cout << "</strategyChoice>";
588 }
589
590 std::cout << "</strategyChoices>";
591 }
592 else
593 {
594 std::cout << "Strategy choices:" << std::endl;
595
596 Block block;
597 size_t offset = 0;
598 while (offset < buf->size())
599 {
600 bool ok = Block::fromBuffer(buf, offset, block);
601 if (!ok)
602 {
603 std::cerr << "ERROR: cannot decode StrategyChoice TLV" << std::endl;
604 break;
605 }
606 offset += block.size();
607
608 nfd::StrategyChoice strategyChoice(block);
609
610 std::cout << " " << strategyChoice.getName()
611 << " strategy=" << strategyChoice.getStrategy() << std::endl;
612 }
613 }
614
615 runNextStep();
616 }
617
618 void
jeraldabrahamb6dde382014-03-19 18:58:09 -0700619 fetchInformation()
620 {
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300621 if (m_isOutputXml ||
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600622 (!m_needVersionRetrieval &&
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300623 !m_needChannelStatusRetrieval &&
624 !m_needFaceStatusRetrieval &&
625 !m_needFibEnumerationRetrieval &&
626 !m_needStrategyChoiceRetrieval))
jeraldabrahamb6dde382014-03-19 18:58:09 -0700627 {
628 enableVersionRetrieval();
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300629 enableChannelStatusRetrieval();
jeraldabrahamb6dde382014-03-19 18:58:09 -0700630 enableFaceStatusRetrieval();
631 enableFibEnumerationRetrieval();
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300632 enableStrategyChoiceRetrieval();
jeraldabrahamb6dde382014-03-19 18:58:09 -0700633 }
634
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300635 if (m_isOutputXml)
636 m_fetchSteps.push_back(bind(&NfdStatus::printXmlHeader, this));
637
jeraldabrahamb6dde382014-03-19 18:58:09 -0700638 if (m_needVersionRetrieval)
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300639 m_fetchSteps.push_back(bind(&NfdStatus::fetchVersionInformation, this));
jeraldabrahamb6dde382014-03-19 18:58:09 -0700640
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300641 if (m_needChannelStatusRetrieval)
642 m_fetchSteps.push_back(bind(&NfdStatus::fetchChannelStatusInformation, this));
643
644 if (m_needFaceStatusRetrieval)
645 m_fetchSteps.push_back(bind(&NfdStatus::fetchFaceStatusInformation, this));
646
647 if (m_needFibEnumerationRetrieval)
648 m_fetchSteps.push_back(bind(&NfdStatus::fetchFibEnumerationInformation, this));
649
650 if (m_needStrategyChoiceRetrieval)
651 m_fetchSteps.push_back(bind(&NfdStatus::fetchStrategyChoiceInformation, this));
652
653 if (m_isOutputXml)
654 m_fetchSteps.push_back(bind(&NfdStatus::printXmlFooter, this));
655
656 runNextStep();
jeraldabrahamb6dde382014-03-19 18:58:09 -0700657 m_face.processEvents();
658 }
659
660private:
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300661 void
662 printXmlHeader()
663 {
664 std::cout << "<?xml version=\"1.0\"?>";
665 std::cout << "<nfdStatus xmlns=\"ndn:/localhost/nfd/status/1\">";
666
667 runNextStep();
668 }
669
670 void
671 printXmlFooter()
672 {
673 std::cout << "</nfdStatus>";
674
675 runNextStep();
676 }
677
678 void
679 runNextStep()
680 {
681 if (m_fetchSteps.empty())
682 return;
683
684 function<void()> nextStep = m_fetchSteps.front();
685 m_fetchSteps.pop_front();
686 nextStep();
687 }
688
689private:
jeraldabrahamb6dde382014-03-19 18:58:09 -0700690 std::string m_toolName;
691 bool m_needVersionRetrieval;
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300692 bool m_needChannelStatusRetrieval;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700693 bool m_needFaceStatusRetrieval;
694 bool m_needFibEnumerationRetrieval;
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300695 bool m_needStrategyChoiceRetrieval;
696 bool m_isOutputXml;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700697 Face m_face;
698
699 shared_ptr<OBufferStream> m_buffer;
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300700
701 std::deque<function<void()> > m_fetchSteps;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700702};
703
704}
705
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700706int main(int argc, char* argv[])
jeraldabrahamb6dde382014-03-19 18:58:09 -0700707{
708 int option;
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700709 ndn::NfdStatus nfdStatus(argv[0]);
jeraldabrahamb6dde382014-03-19 18:58:09 -0700710
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300711 while ((option = getopt(argc, argv, "hvcfbsxV")) != -1) {
jeraldabrahamb6dde382014-03-19 18:58:09 -0700712 switch (option) {
713 case 'h':
714 nfdStatus.usage();
Alexander Afanasyev60a7ba52014-03-23 11:23:06 -0700715 return 0;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700716 case 'v':
717 nfdStatus.enableVersionRetrieval();
718 break;
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300719 case 'c':
720 nfdStatus.enableChannelStatusRetrieval();
721 break;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700722 case 'f':
723 nfdStatus.enableFaceStatusRetrieval();
724 break;
725 case 'b':
726 nfdStatus.enableFibEnumerationRetrieval();
727 break;
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300728 case 's':
729 nfdStatus.enableStrategyChoiceRetrieval();
730 break;
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600731 case 'x':
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300732 nfdStatus.enableXmlOutput();
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600733 break;
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700734 case 'V':
735 std::cout << NFD_VERSION_BUILD_STRING << std::endl;
736 return 0;
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700737 default:
jeraldabrahamb6dde382014-03-19 18:58:09 -0700738 nfdStatus.usage();
739 return 1;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700740 }
741 }
742
743 try {
744 nfdStatus.fetchInformation();
745 }
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700746 catch (std::exception& e) {
jeraldabrahamb6dde382014-03-19 18:58:09 -0700747 std::cerr << "ERROR: " << e.what() << std::endl;
748 return 2;
749 }
750
751 return 0;
752}