blob: f1e5afda7b0346e05402b37410e2fbba67255a56 [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()
161 << " uri=" << faceStatus.getUri()
162 << " counters={"
163 << "in={" << faceStatus.getInInterest() << "i "
164 << faceStatus.getInData() << "d}"
165 << " out={" << faceStatus.getOutInterest() << "i "
166 << faceStatus.getOutData() << "d}"
167 << "}" << std::endl;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700168 }
169
170 if (m_needFibEnumerationRetrieval)
171 {
172 fetchFibEnumerationInformation();
173 }
174 }
175
176 void
177 fetchFaceStatusInformation()
178 {
179 m_buffer = make_shared<OBufferStream>();
180
181 Interest interest("/localhost/nfd/faces/list");
182 interest.setChildSelector(1);
183 interest.setMustBeFresh(true);
184
185 m_face.expressInterest(interest,
186 bind(&NfdStatus::fetchSegments, this, _2,
187 &NfdStatus::afterFetchedFaceStatusInformation),
188 bind(&NfdStatus::onTimeout, this));
189 }
190
191 void
192 afterFetchedFibEnumerationInformation()
193 {
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700194 std::cout << "FIB:" << std::endl;
195
196 ConstBufferPtr buf = m_buffer->buf();
197
198 Block block;
199 size_t offset = 0;
200 while (offset < buf->size())
jeraldabrahamb6dde382014-03-19 18:58:09 -0700201 {
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700202 bool ok = Block::fromBuffer(buf, offset, block);
203 if (!ok)
jeraldabrahamb6dde382014-03-19 18:58:09 -0700204 {
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700205 std::cerr << "ERROR: cannot decode FibEntry TLV" << std::endl;
206 break;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700207 }
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700208 offset += block.size();
209
210 nfd::FibEntry fibEntry(block);
211
212 std::cout << " " << fibEntry.getPrefix() << " nexthops={";
213 for (std::list<nfd::NextHopRecord>::const_iterator
214 nextHop = fibEntry.getNextHopRecords().begin();
215 nextHop != fibEntry.getNextHopRecords().end();
216 ++nextHop)
217 {
218 if (nextHop != fibEntry.getNextHopRecords().begin())
219 std::cout << ", ";
220 std::cout << "faceid=" << nextHop->getFaceId()
221 << " (cost=" << nextHop->getCost() << ")";
222 }
223 std::cout << "}" << std::endl;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700224 }
225 }
226
227 void
228 fetchFibEnumerationInformation()
229 {
230 m_buffer = make_shared<OBufferStream>();
231
232 Interest interest("/localhost/nfd/fib/list");
233 interest.setChildSelector(1);
234 interest.setMustBeFresh(true);
235 m_face.expressInterest(interest,
236 bind(&NfdStatus::fetchSegments, this, _2,
237 &NfdStatus::afterFetchedFibEnumerationInformation),
238 bind(&NfdStatus::onTimeout, this));
239 }
240
241 void
242 fetchInformation()
243 {
244 if (!m_needVersionRetrieval &&
245 !m_needFaceStatusRetrieval &&
246 !m_needFibEnumerationRetrieval)
247 {
248 enableVersionRetrieval();
249 enableFaceStatusRetrieval();
250 enableFibEnumerationRetrieval();
251 }
252
253 if (m_needVersionRetrieval)
254 {
255 fetchVersionInformation();
256 }
257 else if (m_needFaceStatusRetrieval)
258 {
259 fetchFaceStatusInformation();
260 }
261 else if (m_needFibEnumerationRetrieval)
262 {
263 fetchFibEnumerationInformation();
264 }
265
266 m_face.processEvents();
267 }
268
269private:
270 std::string m_toolName;
271 bool m_needVersionRetrieval;
272 bool m_needFaceStatusRetrieval;
273 bool m_needFibEnumerationRetrieval;
274 Face m_face;
275
276 shared_ptr<OBufferStream> m_buffer;
277};
278
279}
280
281int main( int argc, char* argv[] )
282{
283 int option;
284 ndn::NfdStatus nfdStatus (argv[0]);
285
286 while ((option = getopt(argc, argv, "hvfb")) != -1) {
287 switch (option) {
288 case 'h':
289 nfdStatus.usage();
Alexander Afanasyev60a7ba52014-03-23 11:23:06 -0700290 return 0;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700291 case 'v':
292 nfdStatus.enableVersionRetrieval();
293 break;
294 case 'f':
295 nfdStatus.enableFaceStatusRetrieval();
296 break;
297 case 'b':
298 nfdStatus.enableFibEnumerationRetrieval();
299 break;
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700300 default:
jeraldabrahamb6dde382014-03-19 18:58:09 -0700301 nfdStatus.usage();
302 return 1;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700303 }
304 }
305
306 try {
307 nfdStatus.fetchInformation();
308 }
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700309 catch (std::exception& e) {
jeraldabrahamb6dde382014-03-19 18:58:09 -0700310 std::cerr << "ERROR: " << e.what() << std::endl;
311 return 2;
312 }
313
314 return 0;
315}