blob: 2c27c9a29c13fe81aaf96b8166d6a71896179ba6 [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:
21 NfdStatus(char* toolName)
22 : m_toolName(toolName)
23 , m_needVersionRetrieval(false)
24 , m_needFaceStatusRetrieval(false)
25 , m_needFibEnumerationRetrieval(false)
26 , m_face()
27 {
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 {
142 try
143 {
144 std::cout << "Faces:" << std::endl;
145
146 ConstBufferPtr buf = m_buffer->buf();
147
148 size_t offset = 0;
149 while (offset < buf->size())
150 {
151 Block block(buf, buf->begin() + offset, buf->end(), false);
152 offset += block.size();
153
154 nfd::FaceStatus faceStatus(block);
155
156 std::cout << " faceid=" << faceStatus.getFaceId()
157 << " uri=" << faceStatus.getUri()
158 << " counters={"
159 << "in={" << faceStatus.getInInterest() << "i "
160 << faceStatus.getInData() << "d}"
161 << " out={" << faceStatus.getOutInterest() << "i "
162 << faceStatus.getOutData() << "d}"
163 << "}" << std::endl;
164 }
165
166 }
167 catch(Tlv::Error& e)
168 {
169 std::cerr << e.what() << std::endl;
170 }
171
172 if (m_needFibEnumerationRetrieval)
173 {
174 fetchFibEnumerationInformation();
175 }
176 }
177
178 void
179 fetchFaceStatusInformation()
180 {
181 m_buffer = make_shared<OBufferStream>();
182
183 Interest interest("/localhost/nfd/faces/list");
184 interest.setChildSelector(1);
185 interest.setMustBeFresh(true);
186
187 m_face.expressInterest(interest,
188 bind(&NfdStatus::fetchSegments, this, _2,
189 &NfdStatus::afterFetchedFaceStatusInformation),
190 bind(&NfdStatus::onTimeout, this));
191 }
192
193 void
194 afterFetchedFibEnumerationInformation()
195 {
196 try
197 {
198 std::cout << "FIB:" << std::endl;
199
200 ConstBufferPtr buf = m_buffer->buf();
201
202 size_t offset = 0;
203 while (offset < buf->size())
204 {
205 Block block(buf, buf->begin() + offset, buf->end(), false);
206 offset += block.size();
207
208 nfd::FibEntry fibEntry(block);
209
210 std::cout << " " << fibEntry.getPrefix() << " nexthops={";
211 for (std::list<nfd::NextHopRecord>::const_iterator
212 nextHop = fibEntry.getNextHopRecords().begin();
213 nextHop != fibEntry.getNextHopRecords().end();
214 ++nextHop)
215 {
216 if (nextHop != fibEntry.getNextHopRecords().begin())
217 std::cout << ", ";
218 std::cout << "faceid=" << nextHop->getFaceId()
219 << " (cost=" << nextHop->getCost() << ")";
220 }
221 std::cout << "}" << std::endl;
222 }
223 }
224 catch(Tlv::Error& e)
225 {
226 std::cerr << e.what() << std::endl;
227 }
228 }
229
230 void
231 fetchFibEnumerationInformation()
232 {
233 m_buffer = make_shared<OBufferStream>();
234
235 Interest interest("/localhost/nfd/fib/list");
236 interest.setChildSelector(1);
237 interest.setMustBeFresh(true);
238 m_face.expressInterest(interest,
239 bind(&NfdStatus::fetchSegments, this, _2,
240 &NfdStatus::afterFetchedFibEnumerationInformation),
241 bind(&NfdStatus::onTimeout, this));
242 }
243
244 void
245 fetchInformation()
246 {
247 if (!m_needVersionRetrieval &&
248 !m_needFaceStatusRetrieval &&
249 !m_needFibEnumerationRetrieval)
250 {
251 enableVersionRetrieval();
252 enableFaceStatusRetrieval();
253 enableFibEnumerationRetrieval();
254 }
255
256 if (m_needVersionRetrieval)
257 {
258 fetchVersionInformation();
259 }
260 else if (m_needFaceStatusRetrieval)
261 {
262 fetchFaceStatusInformation();
263 }
264 else if (m_needFibEnumerationRetrieval)
265 {
266 fetchFibEnumerationInformation();
267 }
268
269 m_face.processEvents();
270 }
271
272private:
273 std::string m_toolName;
274 bool m_needVersionRetrieval;
275 bool m_needFaceStatusRetrieval;
276 bool m_needFibEnumerationRetrieval;
277 Face m_face;
278
279 shared_ptr<OBufferStream> m_buffer;
280};
281
282}
283
284int main( int argc, char* argv[] )
285{
286 int option;
287 ndn::NfdStatus nfdStatus (argv[0]);
288
289 while ((option = getopt(argc, argv, "hvfb")) != -1) {
290 switch (option) {
291 case 'h':
292 nfdStatus.usage();
293 break;
294 case 'v':
295 nfdStatus.enableVersionRetrieval();
296 break;
297 case 'f':
298 nfdStatus.enableFaceStatusRetrieval();
299 break;
300 case 'b':
301 nfdStatus.enableFibEnumerationRetrieval();
302 break;
303 default :
304 nfdStatus.usage();
305 return 1;
306 break;
307 }
308 }
309
310 try {
311 nfdStatus.fetchInformation();
312 }
313 catch(std::exception& e) {
314 std::cerr << "ERROR: " << e.what() << std::endl;
315 return 2;
316 }
317
318 return 0;
319}