blob: efe128350e4486bc8cd4e07edc492c2e655b837c [file] [log] [blame]
jeraldabrahamb6dde382014-03-19 18:58:09 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
3 * Copyright (C) 2014 University of Arizona.
4 *
5 * Author: Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
6 */
7
8#include <ndn-cpp-dev/face.hpp>
9#include <ndn-cpp-dev/name.hpp>
10#include <ndn-cpp-dev/interest.hpp>
11
12#include <ndn-cpp-dev/management/nfd-fib-entry.hpp>
13#include <ndn-cpp-dev/management/nfd-face-status.hpp>
Junxiao Shi88d69372014-03-28 11:52:39 -070014#include <ndn-cpp-dev/management/nfd-forwarder-status.hpp>
jeraldabrahamb6dde382014-03-19 18:58:09 -070015
16namespace ndn {
17
18class NfdStatus
19{
20public:
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -070021 explicit
jeraldabrahamb6dde382014-03-19 18:58:09 -070022 NfdStatus(char* toolName)
23 : m_toolName(toolName)
24 , m_needVersionRetrieval(false)
25 , m_needFaceStatusRetrieval(false)
26 , m_needFibEnumerationRetrieval(false)
jeraldabrahamb6dde382014-03-19 18:58:09 -070027 {
28 }
29
30 void
31 usage()
32 {
Alexander Afanasyev60a7ba52014-03-23 11:23:06 -070033 std::cout << "Usage: \n " << m_toolName << " [options]\n\n"
34 "Show NFD version and status information\n\n"
35 "Options:\n"
36 " [-h] - print this help message\n"
jeraldabrahamb6dde382014-03-19 18:58:09 -070037 " [-v] - retrieve version information\n"
38 " [-f] - retrieve face status information\n"
Alexander Afanasyev60a7ba52014-03-23 11:23:06 -070039 " [-b] - retrieve FIB information\n\n"
40 "If no options are provided, all information is retrieved.\n"
41 ;
jeraldabrahamb6dde382014-03-19 18:58:09 -070042 }
43
44 void
45 enableVersionRetrieval()
46 {
47 m_needVersionRetrieval = true;
48 }
49
50 void
51 enableFaceStatusRetrieval()
52 {
53 m_needFaceStatusRetrieval = true;
54 }
55
56 void
57 enableFibEnumerationRetrieval()
58 {
59 m_needFibEnumerationRetrieval = true;
60 }
61
62 void
63 onTimeout()
64 {
65 std::cerr << "Request timed out" << std::endl;
66 }
67
68 void
69 fetchSegments(const Data& data, void (NfdStatus::*onDone)())
70 {
71 m_buffer->write((const char*)data.getContent().value(),
72 data.getContent().value_size());
73
74 uint64_t currentSegment = data.getName().get(-1).toSegment();
75
76 const name::Component& finalBlockId = data.getMetaInfo().getFinalBlockId();
77 if (finalBlockId.empty() ||
78 finalBlockId.toSegment() > currentSegment)
79 {
80 m_face.expressInterest(data.getName().getPrefix(-1).appendSegment(currentSegment+1),
81 bind(&NfdStatus::fetchSegments, this, _2, onDone),
82 bind(&NfdStatus::onTimeout, this));
83 }
84 else
85 {
86 return (this->*onDone)();
87 }
88 }
89
90 void
91 afterFetchedVersionInformation(const Data& data)
92 {
93 std::cout << "General NFD status:" << std::endl;
94
Junxiao Shi88d69372014-03-28 11:52:39 -070095 nfd::ForwarderStatus status(data.getContent());
jeraldabrahamb6dde382014-03-19 18:58:09 -070096 std::cout << " version="
97 << status.getNfdVersion() << std::endl;
98 std::cout << " startTime="
99 << time::toIsoString(status.getStartTimestamp()) << std::endl;
100 std::cout << " currentTime="
101 << time::toIsoString(status.getCurrentTimestamp()) << std::endl;
102 std::cout << " uptime="
103 << time::duration_cast<time::seconds>(status.getCurrentTimestamp()
104 - status.getStartTimestamp()) << std::endl;
105
106 std::cout << " nNameTreeEntries=" << status.getNNameTreeEntries() << std::endl;
107 std::cout << " nFibEntries=" << status.getNFibEntries() << std::endl;
108 std::cout << " nPitEntries=" << status.getNPitEntries() << std::endl;
109 std::cout << " nMeasurementsEntries=" << status.getNMeasurementsEntries() << std::endl;
110 std::cout << " nCsEntries=" << status.getNCsEntries() << std::endl;
111 std::cout << " nInInterests=" << status.getNInInterests() << std::endl;
112 std::cout << " nOutInterests=" << status.getNOutInterests() << std::endl;
113 std::cout << " nInDatas=" << status.getNInDatas() << std::endl;
114 std::cout << " nOutDatas=" << status.getNOutDatas() << std::endl;
115
116 if (m_needFaceStatusRetrieval)
117 {
118 fetchFaceStatusInformation();
119 }
120 else if (m_needFibEnumerationRetrieval)
121 {
122 fetchFibEnumerationInformation();
123 }
124 }
125
126 void
127 fetchVersionInformation()
128 {
129 Interest interest("/localhost/nfd/status");
130 interest.setChildSelector(1);
131 interest.setMustBeFresh(true);
132 m_face.expressInterest(
133 interest,
134 bind(&NfdStatus::afterFetchedVersionInformation, this, _2),
135 bind(&NfdStatus::onTimeout, this));
136 }
137
138 void
139 afterFetchedFaceStatusInformation()
140 {
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700141 std::cout << "Faces:" << std::endl;
142
143 ConstBufferPtr buf = m_buffer->buf();
144
145 Block block;
146 size_t offset = 0;
147 while (offset < buf->size())
jeraldabrahamb6dde382014-03-19 18:58:09 -0700148 {
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700149 bool ok = Block::fromBuffer(buf, offset, block);
150 if (!ok)
jeraldabrahamb6dde382014-03-19 18:58:09 -0700151 {
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700152 std::cerr << "ERROR: cannot decode FaceStatus TLV" << std::endl;
153 break;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700154 }
155
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700156 offset += block.size();
157
158 nfd::FaceStatus faceStatus(block);
159
160 std::cout << " faceid=" << faceStatus.getFaceId()
Junxiao Shi6e694322014-04-03 10:27:13 -0700161 << " remote=" << faceStatus.getRemoteUri()
162 << " local=" << faceStatus.getLocalUri()
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700163 << " counters={"
Junxiao Shi6e694322014-04-03 10:27:13 -0700164 << "in={" << faceStatus.getNInInterests() << "i "
165 << faceStatus.getNInDatas() << "d}"
166 << " out={" << faceStatus.getNOutInterests() << "i "
167 << faceStatus.getNOutDatas() << "d}"
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700168 << "}" << std::endl;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700169 }
170
171 if (m_needFibEnumerationRetrieval)
172 {
173 fetchFibEnumerationInformation();
174 }
175 }
176
177 void
178 fetchFaceStatusInformation()
179 {
180 m_buffer = make_shared<OBufferStream>();
181
182 Interest interest("/localhost/nfd/faces/list");
183 interest.setChildSelector(1);
184 interest.setMustBeFresh(true);
185
186 m_face.expressInterest(interest,
187 bind(&NfdStatus::fetchSegments, this, _2,
188 &NfdStatus::afterFetchedFaceStatusInformation),
189 bind(&NfdStatus::onTimeout, this));
190 }
191
192 void
193 afterFetchedFibEnumerationInformation()
194 {
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700195 std::cout << "FIB:" << std::endl;
196
197 ConstBufferPtr buf = m_buffer->buf();
198
199 Block block;
200 size_t offset = 0;
201 while (offset < buf->size())
jeraldabrahamb6dde382014-03-19 18:58:09 -0700202 {
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700203 bool ok = Block::fromBuffer(buf, offset, block);
204 if (!ok)
jeraldabrahamb6dde382014-03-19 18:58:09 -0700205 {
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700206 std::cerr << "ERROR: cannot decode FibEntry TLV" << std::endl;
207 break;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700208 }
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700209 offset += block.size();
210
211 nfd::FibEntry fibEntry(block);
212
213 std::cout << " " << fibEntry.getPrefix() << " nexthops={";
214 for (std::list<nfd::NextHopRecord>::const_iterator
215 nextHop = fibEntry.getNextHopRecords().begin();
216 nextHop != fibEntry.getNextHopRecords().end();
217 ++nextHop)
218 {
219 if (nextHop != fibEntry.getNextHopRecords().begin())
220 std::cout << ", ";
221 std::cout << "faceid=" << nextHop->getFaceId()
222 << " (cost=" << nextHop->getCost() << ")";
223 }
224 std::cout << "}" << std::endl;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700225 }
226 }
227
228 void
229 fetchFibEnumerationInformation()
230 {
231 m_buffer = make_shared<OBufferStream>();
232
233 Interest interest("/localhost/nfd/fib/list");
234 interest.setChildSelector(1);
235 interest.setMustBeFresh(true);
236 m_face.expressInterest(interest,
237 bind(&NfdStatus::fetchSegments, this, _2,
238 &NfdStatus::afterFetchedFibEnumerationInformation),
239 bind(&NfdStatus::onTimeout, this));
240 }
241
242 void
243 fetchInformation()
244 {
245 if (!m_needVersionRetrieval &&
246 !m_needFaceStatusRetrieval &&
247 !m_needFibEnumerationRetrieval)
248 {
249 enableVersionRetrieval();
250 enableFaceStatusRetrieval();
251 enableFibEnumerationRetrieval();
252 }
253
254 if (m_needVersionRetrieval)
255 {
256 fetchVersionInformation();
257 }
258 else if (m_needFaceStatusRetrieval)
259 {
260 fetchFaceStatusInformation();
261 }
262 else if (m_needFibEnumerationRetrieval)
263 {
264 fetchFibEnumerationInformation();
265 }
266
267 m_face.processEvents();
268 }
269
270private:
271 std::string m_toolName;
272 bool m_needVersionRetrieval;
273 bool m_needFaceStatusRetrieval;
274 bool m_needFibEnumerationRetrieval;
275 Face m_face;
276
277 shared_ptr<OBufferStream> m_buffer;
278};
279
280}
281
282int main( int argc, char* argv[] )
283{
284 int option;
285 ndn::NfdStatus nfdStatus (argv[0]);
286
287 while ((option = getopt(argc, argv, "hvfb")) != -1) {
288 switch (option) {
289 case 'h':
290 nfdStatus.usage();
Alexander Afanasyev60a7ba52014-03-23 11:23:06 -0700291 return 0;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700292 case 'v':
293 nfdStatus.enableVersionRetrieval();
294 break;
295 case 'f':
296 nfdStatus.enableFaceStatusRetrieval();
297 break;
298 case 'b':
299 nfdStatus.enableFibEnumerationRetrieval();
300 break;
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700301 default:
jeraldabrahamb6dde382014-03-19 18:58:09 -0700302 nfdStatus.usage();
303 return 1;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700304 }
305 }
306
307 try {
308 nfdStatus.fetchInformation();
309 }
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700310 catch (std::exception& e) {
jeraldabrahamb6dde382014-03-19 18:58:09 -0700311 std::cerr << "ERROR: " << e.what() << std::endl;
312 return 2;
313 }
314
315 return 0;
316}