blob: d06e8fb0d268bb687c543a4fe9035c2497789aec [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>";
Alexander Afanasyev40c61f72014-06-30 17:21:01 -0700372
373 if (faceStatus.hasExpirationPeriod()) {
374 std::cout << "<expirationPeriod>PT"
375 << time::duration_cast<time::seconds>(faceStatus.getExpirationPeriod())
376 .count() << "S"
377 << "</expirationPeriod>";
378 }
379
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600380 std::cout << "<packetCounters>";
381 std::cout << "<incomingPackets>";
382 std::cout << "<nInterests>" << faceStatus.getNInInterests()
383 << "</nInterests>";
384 std::cout << "<nDatas>" << faceStatus.getNInInterests()
385 << "</nDatas>";
386 std::cout << "</incomingPackets>";
387 std::cout << "<outgoingPackets>";
388 std::cout << "<nInterests>" << faceStatus.getNOutInterests()
389 << "</nInterests>";
390 std::cout << "<nDatas>" << faceStatus.getNOutInterests()
391 << "</nDatas>";
392 std::cout << "</outgoingPackets>";
393 std::cout << "</packetCounters>";
Alexander Afanasyevd3967a22014-06-30 12:22:10 -0700394
395 if (faceStatus.getFlags() != 0) {
396 std::cout << "<flags>";
397 if (faceStatus.isLocal()) {
398 std::cout << "<local/>";
399 }
400 if (faceStatus.isOnDemand()) {
401 std::cout << "<on-demand/>";
402 }
403 std::cout << "</flags>";
404 }
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600405 std::cout << "</face>";
jeraldabrahamb6dde382014-03-19 18:58:09 -0700406 }
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600407 std::cout << "</faces>";
jeraldabrahamb6dde382014-03-19 18:58:09 -0700408 }
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600409 else
410 {
411 std::cout << "Faces:" << std::endl;
412
413 Block block;
414 size_t offset = 0;
415 while (offset < buf->size())
416 {
417 bool ok = Block::fromBuffer(buf, offset, block);
418 if (!ok)
419 {
420 std::cerr << "ERROR: cannot decode FaceStatus TLV" << std::endl;
421 break;
422 }
423
424 offset += block.size();
425
426 nfd::FaceStatus faceStatus(block);
427
428 std::cout << " faceid=" << faceStatus.getFaceId()
429 << " remote=" << faceStatus.getRemoteUri()
Alexander Afanasyev40c61f72014-06-30 17:21:01 -0700430 << " local=" << faceStatus.getLocalUri();
431 if (faceStatus.hasExpirationPeriod()) {
432 std::cout << " expires="
433 << time::duration_cast<time::seconds>(faceStatus.getExpirationPeriod())
434 .count() << "s";
435 }
436 std::cout << " counters={"
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600437 << "in={" << faceStatus.getNInInterests() << "i "
438 << faceStatus.getNInDatas() << "d}"
439 << " out={" << faceStatus.getNOutInterests() << "i "
440 << faceStatus.getNOutDatas() << "d}"
Alexander Afanasyevd3967a22014-06-30 12:22:10 -0700441 << "}";
442 if (faceStatus.isLocal())
443 std::cout << " local";
444 if (faceStatus.isOnDemand())
445 std::cout << " on-demand";
446 std::cout << std::endl;
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600447 }
448 }
jeraldabrahamb6dde382014-03-19 18:58:09 -0700449
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300450 runNextStep();
jeraldabrahamb6dde382014-03-19 18:58:09 -0700451 }
452
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300453 //////////////////////////////////////////////////////////////////////////////////
454 //////////////////////////////////////////////////////////////////////////////////
455
jeraldabrahamb6dde382014-03-19 18:58:09 -0700456 void
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300457 fetchFibEnumerationInformation()
jeraldabrahamb6dde382014-03-19 18:58:09 -0700458 {
459 m_buffer = make_shared<OBufferStream>();
460
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300461 Interest interest("/localhost/nfd/fib/list");
jeraldabrahamb6dde382014-03-19 18:58:09 -0700462 interest.setChildSelector(1);
463 interest.setMustBeFresh(true);
jeraldabrahamb6dde382014-03-19 18:58:09 -0700464 m_face.expressInterest(interest,
465 bind(&NfdStatus::fetchSegments, this, _2,
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300466 &NfdStatus::afterFetchedFibEnumerationInformation),
jeraldabrahamb6dde382014-03-19 18:58:09 -0700467 bind(&NfdStatus::onTimeout, this));
468 }
469
470 void
471 afterFetchedFibEnumerationInformation()
472 {
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700473 ConstBufferPtr buf = m_buffer->buf();
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300474 if (m_isOutputXml)
jeraldabrahamb6dde382014-03-19 18:58:09 -0700475 {
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600476 std::cout << "<fib>";
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700477
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600478 Block block;
479 size_t offset = 0;
480 while (offset < buf->size())
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700481 {
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600482 bool ok = Block::fromBuffer(buf, offset, block);
483 if (!ok)
484 {
485 std::cerr << "ERROR: cannot decode FibEntry TLV";
486 break;
487 }
488 offset += block.size();
489
490 nfd::FibEntry fibEntry(block);
491
492 std::cout << "<fibEntry>";
493 std::string prefix(fibEntry.getPrefix().toUri());
494 escapeSpecialCharacters(&prefix);
495 std::cout << "<prefix>" << prefix << "</prefix>";
496 std::cout << "<nextHops>";
497 for (std::list<nfd::NextHopRecord>::const_iterator
498 nextHop = fibEntry.getNextHopRecords().begin();
499 nextHop != fibEntry.getNextHopRecords().end();
500 ++nextHop)
501 {
502 std::cout << "<nextHop>" ;
503 std::cout << "<faceId>" << nextHop->getFaceId() << "</faceId>";
504 std::cout << "<cost>" << nextHop->getCost() << "</cost>";
505 std::cout << "</nextHop>";
506 }
507 std::cout << "</nextHops>";
508 std::cout << "</fibEntry>";
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700509 }
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600510
511 std::cout << "</fib>";
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600512 }
513 else
514 {
515 std::cout << "FIB:" << std::endl;
516
517 Block block;
518 size_t offset = 0;
519 while (offset < buf->size())
520 {
521 bool ok = Block::fromBuffer(buf, offset, block);
522 if (!ok)
523 {
524 std::cerr << "ERROR: cannot decode FibEntry TLV" << std::endl;
525 break;
526 }
527 offset += block.size();
528
529 nfd::FibEntry fibEntry(block);
530
531 std::cout << " " << fibEntry.getPrefix() << " nexthops={";
532 for (std::list<nfd::NextHopRecord>::const_iterator
533 nextHop = fibEntry.getNextHopRecords().begin();
534 nextHop != fibEntry.getNextHopRecords().end();
535 ++nextHop)
536 {
537 if (nextHop != fibEntry.getNextHopRecords().begin())
538 std::cout << ", ";
539 std::cout << "faceid=" << nextHop->getFaceId()
540 << " (cost=" << nextHop->getCost() << ")";
541 }
542 std::cout << "}" << std::endl;
543 }
jeraldabrahamb6dde382014-03-19 18:58:09 -0700544 }
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300545
546 runNextStep();
jeraldabrahamb6dde382014-03-19 18:58:09 -0700547 }
548
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300549 //////////////////////////////////////////////////////////////////////////////////
550 //////////////////////////////////////////////////////////////////////////////////
551
jeraldabrahamb6dde382014-03-19 18:58:09 -0700552 void
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300553 fetchStrategyChoiceInformation()
jeraldabrahamb6dde382014-03-19 18:58:09 -0700554 {
555 m_buffer = make_shared<OBufferStream>();
556
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300557 Interest interest("/localhost/nfd/strategy-choice/list");
jeraldabrahamb6dde382014-03-19 18:58:09 -0700558 interest.setChildSelector(1);
559 interest.setMustBeFresh(true);
560 m_face.expressInterest(interest,
561 bind(&NfdStatus::fetchSegments, this, _2,
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300562 &NfdStatus::afterFetchedStrategyChoiceInformationInformation),
jeraldabrahamb6dde382014-03-19 18:58:09 -0700563 bind(&NfdStatus::onTimeout, this));
564 }
565
566 void
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300567 afterFetchedStrategyChoiceInformationInformation()
568 {
569 ConstBufferPtr buf = m_buffer->buf();
570 if (m_isOutputXml)
571 {
572 std::cout << "<strategyChoices>";
573
574 Block block;
575 size_t offset = 0;
576 while (offset < buf->size())
577 {
578 bool ok = Block::fromBuffer(buf, offset, block);
579 if (!ok)
580 {
581 std::cerr << "ERROR: cannot decode StrategyChoice TLV";
582 break;
583 }
584 offset += block.size();
585
586 nfd::StrategyChoice strategyChoice(block);
587
588 std::cout << "<strategyChoice>";
589
590 std::string name(strategyChoice.getName().toUri());
591 escapeSpecialCharacters(&name);
592 std::cout << "<namespace>" << name << "</namespace>";
593 std::cout << "<strategy>";
594
595 std::string strategy(strategyChoice.getStrategy().toUri());
596 escapeSpecialCharacters(&strategy);
597
598 std::cout << "<name>" << strategy << "</name>";
599 std::cout << "</strategy>";
600 std::cout << "</strategyChoice>";
601 }
602
603 std::cout << "</strategyChoices>";
604 }
605 else
606 {
607 std::cout << "Strategy choices:" << std::endl;
608
609 Block block;
610 size_t offset = 0;
611 while (offset < buf->size())
612 {
613 bool ok = Block::fromBuffer(buf, offset, block);
614 if (!ok)
615 {
616 std::cerr << "ERROR: cannot decode StrategyChoice TLV" << std::endl;
617 break;
618 }
619 offset += block.size();
620
621 nfd::StrategyChoice strategyChoice(block);
622
623 std::cout << " " << strategyChoice.getName()
624 << " strategy=" << strategyChoice.getStrategy() << std::endl;
625 }
626 }
627
628 runNextStep();
629 }
630
631 void
jeraldabrahamb6dde382014-03-19 18:58:09 -0700632 fetchInformation()
633 {
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300634 if (m_isOutputXml ||
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600635 (!m_needVersionRetrieval &&
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300636 !m_needChannelStatusRetrieval &&
637 !m_needFaceStatusRetrieval &&
638 !m_needFibEnumerationRetrieval &&
639 !m_needStrategyChoiceRetrieval))
jeraldabrahamb6dde382014-03-19 18:58:09 -0700640 {
641 enableVersionRetrieval();
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300642 enableChannelStatusRetrieval();
jeraldabrahamb6dde382014-03-19 18:58:09 -0700643 enableFaceStatusRetrieval();
644 enableFibEnumerationRetrieval();
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300645 enableStrategyChoiceRetrieval();
jeraldabrahamb6dde382014-03-19 18:58:09 -0700646 }
647
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300648 if (m_isOutputXml)
649 m_fetchSteps.push_back(bind(&NfdStatus::printXmlHeader, this));
650
jeraldabrahamb6dde382014-03-19 18:58:09 -0700651 if (m_needVersionRetrieval)
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300652 m_fetchSteps.push_back(bind(&NfdStatus::fetchVersionInformation, this));
jeraldabrahamb6dde382014-03-19 18:58:09 -0700653
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300654 if (m_needChannelStatusRetrieval)
655 m_fetchSteps.push_back(bind(&NfdStatus::fetchChannelStatusInformation, this));
656
657 if (m_needFaceStatusRetrieval)
658 m_fetchSteps.push_back(bind(&NfdStatus::fetchFaceStatusInformation, this));
659
660 if (m_needFibEnumerationRetrieval)
661 m_fetchSteps.push_back(bind(&NfdStatus::fetchFibEnumerationInformation, this));
662
663 if (m_needStrategyChoiceRetrieval)
664 m_fetchSteps.push_back(bind(&NfdStatus::fetchStrategyChoiceInformation, this));
665
666 if (m_isOutputXml)
667 m_fetchSteps.push_back(bind(&NfdStatus::printXmlFooter, this));
668
669 runNextStep();
jeraldabrahamb6dde382014-03-19 18:58:09 -0700670 m_face.processEvents();
671 }
672
673private:
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300674 void
675 printXmlHeader()
676 {
677 std::cout << "<?xml version=\"1.0\"?>";
678 std::cout << "<nfdStatus xmlns=\"ndn:/localhost/nfd/status/1\">";
679
680 runNextStep();
681 }
682
683 void
684 printXmlFooter()
685 {
686 std::cout << "</nfdStatus>";
687
688 runNextStep();
689 }
690
691 void
692 runNextStep()
693 {
694 if (m_fetchSteps.empty())
695 return;
696
697 function<void()> nextStep = m_fetchSteps.front();
698 m_fetchSteps.pop_front();
699 nextStep();
700 }
701
702private:
jeraldabrahamb6dde382014-03-19 18:58:09 -0700703 std::string m_toolName;
704 bool m_needVersionRetrieval;
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300705 bool m_needChannelStatusRetrieval;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700706 bool m_needFaceStatusRetrieval;
707 bool m_needFibEnumerationRetrieval;
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300708 bool m_needStrategyChoiceRetrieval;
709 bool m_isOutputXml;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700710 Face m_face;
711
712 shared_ptr<OBufferStream> m_buffer;
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300713
714 std::deque<function<void()> > m_fetchSteps;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700715};
716
717}
718
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700719int main(int argc, char* argv[])
jeraldabrahamb6dde382014-03-19 18:58:09 -0700720{
721 int option;
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700722 ndn::NfdStatus nfdStatus(argv[0]);
jeraldabrahamb6dde382014-03-19 18:58:09 -0700723
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300724 while ((option = getopt(argc, argv, "hvcfbsxV")) != -1) {
jeraldabrahamb6dde382014-03-19 18:58:09 -0700725 switch (option) {
726 case 'h':
727 nfdStatus.usage();
Alexander Afanasyev60a7ba52014-03-23 11:23:06 -0700728 return 0;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700729 case 'v':
730 nfdStatus.enableVersionRetrieval();
731 break;
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300732 case 'c':
733 nfdStatus.enableChannelStatusRetrieval();
734 break;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700735 case 'f':
736 nfdStatus.enableFaceStatusRetrieval();
737 break;
738 case 'b':
739 nfdStatus.enableFibEnumerationRetrieval();
740 break;
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300741 case 's':
742 nfdStatus.enableStrategyChoiceRetrieval();
743 break;
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600744 case 'x':
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300745 nfdStatus.enableXmlOutput();
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600746 break;
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700747 case 'V':
748 std::cout << NFD_VERSION_BUILD_STRING << std::endl;
749 return 0;
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700750 default:
jeraldabrahamb6dde382014-03-19 18:58:09 -0700751 nfdStatus.usage();
752 return 1;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700753 }
754 }
755
756 try {
757 nfdStatus.fetchInformation();
758 }
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700759 catch (std::exception& e) {
jeraldabrahamb6dde382014-03-19 18:58:09 -0700760 std::cerr << "ERROR: " << e.what() << std::endl;
761 return 2;
762 }
763
764 return 0;
765}