blob: ff6316f7a1faf5c8eb59dfccf76c8a29e439851b [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>
14#include <ndn-cpp-dev/management/nfd-status.hpp>
15
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 {
33 std::cout << "\nUsage: " << m_toolName << " [options]\n"
34 "Shows NFD Status Information\n"
35 "Displays Version Information (NFD Version, Start Timestamp, Current Timestamp).\n"
36 "Face Status Information via NFD Face Status Protocol (FaceID, URI, Counters).\n"
37 "FIB Information via NFD FIB Enumeration Protocol (Prefix, Nexthop).\n"
38 "If no options are provided, all information is retrieved.\n"
39 " [-v] - retrieve version information\n"
40 " [-f] - retrieve face status information\n"
41 " [-b] - retrieve FIB information\n"
42 " [-h] - print help and exit\n\n";
43 }
44
45 void
46 enableVersionRetrieval()
47 {
48 m_needVersionRetrieval = true;
49 }
50
51 void
52 enableFaceStatusRetrieval()
53 {
54 m_needFaceStatusRetrieval = true;
55 }
56
57 void
58 enableFibEnumerationRetrieval()
59 {
60 m_needFibEnumerationRetrieval = true;
61 }
62
63 void
64 onTimeout()
65 {
66 std::cerr << "Request timed out" << std::endl;
67 }
68
69 void
70 fetchSegments(const Data& data, void (NfdStatus::*onDone)())
71 {
72 m_buffer->write((const char*)data.getContent().value(),
73 data.getContent().value_size());
74
75 uint64_t currentSegment = data.getName().get(-1).toSegment();
76
77 const name::Component& finalBlockId = data.getMetaInfo().getFinalBlockId();
78 if (finalBlockId.empty() ||
79 finalBlockId.toSegment() > currentSegment)
80 {
81 m_face.expressInterest(data.getName().getPrefix(-1).appendSegment(currentSegment+1),
82 bind(&NfdStatus::fetchSegments, this, _2, onDone),
83 bind(&NfdStatus::onTimeout, this));
84 }
85 else
86 {
87 return (this->*onDone)();
88 }
89 }
90
91 void
92 afterFetchedVersionInformation(const Data& data)
93 {
94 std::cout << "General NFD status:" << std::endl;
95
96 nfd::Status status(data.getContent());
97 std::cout << " version="
98 << status.getNfdVersion() << std::endl;
99 std::cout << " startTime="
100 << time::toIsoString(status.getStartTimestamp()) << std::endl;
101 std::cout << " currentTime="
102 << time::toIsoString(status.getCurrentTimestamp()) << std::endl;
103 std::cout << " uptime="
104 << time::duration_cast<time::seconds>(status.getCurrentTimestamp()
105 - status.getStartTimestamp()) << std::endl;
106
107 std::cout << " nNameTreeEntries=" << status.getNNameTreeEntries() << std::endl;
108 std::cout << " nFibEntries=" << status.getNFibEntries() << std::endl;
109 std::cout << " nPitEntries=" << status.getNPitEntries() << std::endl;
110 std::cout << " nMeasurementsEntries=" << status.getNMeasurementsEntries() << std::endl;
111 std::cout << " nCsEntries=" << status.getNCsEntries() << std::endl;
112 std::cout << " nInInterests=" << status.getNInInterests() << std::endl;
113 std::cout << " nOutInterests=" << status.getNOutInterests() << std::endl;
114 std::cout << " nInDatas=" << status.getNInDatas() << std::endl;
115 std::cout << " nOutDatas=" << status.getNOutDatas() << std::endl;
116
117 if (m_needFaceStatusRetrieval)
118 {
119 fetchFaceStatusInformation();
120 }
121 else if (m_needFibEnumerationRetrieval)
122 {
123 fetchFibEnumerationInformation();
124 }
125 }
126
127 void
128 fetchVersionInformation()
129 {
130 Interest interest("/localhost/nfd/status");
131 interest.setChildSelector(1);
132 interest.setMustBeFresh(true);
133 m_face.expressInterest(
134 interest,
135 bind(&NfdStatus::afterFetchedVersionInformation, this, _2),
136 bind(&NfdStatus::onTimeout, this));
137 }
138
139 void
140 afterFetchedFaceStatusInformation()
141 {
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700142 std::cout << "Faces:" << std::endl;
143
144 ConstBufferPtr buf = m_buffer->buf();
145
146 Block block;
147 size_t offset = 0;
148 while (offset < buf->size())
jeraldabrahamb6dde382014-03-19 18:58:09 -0700149 {
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700150 bool ok = Block::fromBuffer(buf, offset, block);
151 if (!ok)
jeraldabrahamb6dde382014-03-19 18:58:09 -0700152 {
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700153 std::cerr << "ERROR: cannot decode FaceStatus TLV" << std::endl;
154 break;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700155 }
156
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700157 offset += block.size();
158
159 nfd::FaceStatus faceStatus(block);
160
161 std::cout << " faceid=" << faceStatus.getFaceId()
162 << " uri=" << faceStatus.getUri()
163 << " counters={"
164 << "in={" << faceStatus.getInInterest() << "i "
165 << faceStatus.getInData() << "d}"
166 << " out={" << faceStatus.getOutInterest() << "i "
167 << faceStatus.getOutData() << "d}"
168 << "}" << 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();
291 break;
292 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}