blob: 1c1f415af27e12d5eb95dac67138972c3c09dbc4 [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 Afanasyev4a771362014-04-24 21:29:33 -070028#include <ndn-cxx/face.hpp>
29#include <ndn-cxx/name.hpp>
30#include <ndn-cxx/interest.hpp>
jeraldabrahamb6dde382014-03-19 18:58:09 -070031
Alexander Afanasyev4a771362014-04-24 21:29:33 -070032#include <ndn-cxx/management/nfd-fib-entry.hpp>
33#include <ndn-cxx/management/nfd-face-status.hpp>
34#include <ndn-cxx/management/nfd-forwarder-status.hpp>
jeraldabrahamb6dde382014-03-19 18:58:09 -070035
36namespace ndn {
37
38class NfdStatus
39{
40public:
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -070041 explicit
jeraldabrahamb6dde382014-03-19 18:58:09 -070042 NfdStatus(char* toolName)
43 : m_toolName(toolName)
44 , m_needVersionRetrieval(false)
45 , m_needFaceStatusRetrieval(false)
46 , m_needFibEnumerationRetrieval(false)
jeraldabrahamb6dde382014-03-19 18:58:09 -070047 {
48 }
49
50 void
51 usage()
52 {
Alexander Afanasyev60a7ba52014-03-23 11:23:06 -070053 std::cout << "Usage: \n " << m_toolName << " [options]\n\n"
54 "Show NFD version and status information\n\n"
55 "Options:\n"
56 " [-h] - print this help message\n"
jeraldabrahamb6dde382014-03-19 18:58:09 -070057 " [-v] - retrieve version information\n"
58 " [-f] - retrieve face status information\n"
Alexander Afanasyev60a7ba52014-03-23 11:23:06 -070059 " [-b] - retrieve FIB information\n\n"
60 "If no options are provided, all information is retrieved.\n"
61 ;
jeraldabrahamb6dde382014-03-19 18:58:09 -070062 }
63
64 void
65 enableVersionRetrieval()
66 {
67 m_needVersionRetrieval = true;
68 }
69
70 void
71 enableFaceStatusRetrieval()
72 {
73 m_needFaceStatusRetrieval = true;
74 }
75
76 void
77 enableFibEnumerationRetrieval()
78 {
79 m_needFibEnumerationRetrieval = true;
80 }
81
82 void
83 onTimeout()
84 {
85 std::cerr << "Request timed out" << std::endl;
86 }
87
88 void
89 fetchSegments(const Data& data, void (NfdStatus::*onDone)())
90 {
91 m_buffer->write((const char*)data.getContent().value(),
92 data.getContent().value_size());
93
94 uint64_t currentSegment = data.getName().get(-1).toSegment();
95
96 const name::Component& finalBlockId = data.getMetaInfo().getFinalBlockId();
97 if (finalBlockId.empty() ||
98 finalBlockId.toSegment() > currentSegment)
99 {
100 m_face.expressInterest(data.getName().getPrefix(-1).appendSegment(currentSegment+1),
101 bind(&NfdStatus::fetchSegments, this, _2, onDone),
102 bind(&NfdStatus::onTimeout, this));
103 }
104 else
105 {
106 return (this->*onDone)();
107 }
108 }
109
110 void
111 afterFetchedVersionInformation(const Data& data)
112 {
113 std::cout << "General NFD status:" << std::endl;
114
Junxiao Shi88d69372014-03-28 11:52:39 -0700115 nfd::ForwarderStatus status(data.getContent());
jeraldabrahamb6dde382014-03-19 18:58:09 -0700116 std::cout << " version="
117 << status.getNfdVersion() << std::endl;
118 std::cout << " startTime="
119 << time::toIsoString(status.getStartTimestamp()) << std::endl;
120 std::cout << " currentTime="
121 << time::toIsoString(status.getCurrentTimestamp()) << std::endl;
122 std::cout << " uptime="
123 << time::duration_cast<time::seconds>(status.getCurrentTimestamp()
124 - status.getStartTimestamp()) << std::endl;
125
126 std::cout << " nNameTreeEntries=" << status.getNNameTreeEntries() << std::endl;
127 std::cout << " nFibEntries=" << status.getNFibEntries() << std::endl;
128 std::cout << " nPitEntries=" << status.getNPitEntries() << std::endl;
129 std::cout << " nMeasurementsEntries=" << status.getNMeasurementsEntries() << std::endl;
130 std::cout << " nCsEntries=" << status.getNCsEntries() << std::endl;
131 std::cout << " nInInterests=" << status.getNInInterests() << std::endl;
132 std::cout << " nOutInterests=" << status.getNOutInterests() << std::endl;
133 std::cout << " nInDatas=" << status.getNInDatas() << std::endl;
134 std::cout << " nOutDatas=" << status.getNOutDatas() << std::endl;
135
136 if (m_needFaceStatusRetrieval)
137 {
138 fetchFaceStatusInformation();
139 }
140 else if (m_needFibEnumerationRetrieval)
141 {
142 fetchFibEnumerationInformation();
143 }
144 }
145
146 void
147 fetchVersionInformation()
148 {
149 Interest interest("/localhost/nfd/status");
150 interest.setChildSelector(1);
151 interest.setMustBeFresh(true);
152 m_face.expressInterest(
153 interest,
154 bind(&NfdStatus::afterFetchedVersionInformation, this, _2),
155 bind(&NfdStatus::onTimeout, this));
156 }
157
158 void
159 afterFetchedFaceStatusInformation()
160 {
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700161 std::cout << "Faces:" << std::endl;
162
163 ConstBufferPtr buf = m_buffer->buf();
164
165 Block block;
166 size_t offset = 0;
167 while (offset < buf->size())
jeraldabrahamb6dde382014-03-19 18:58:09 -0700168 {
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700169 bool ok = Block::fromBuffer(buf, offset, block);
170 if (!ok)
jeraldabrahamb6dde382014-03-19 18:58:09 -0700171 {
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700172 std::cerr << "ERROR: cannot decode FaceStatus TLV" << std::endl;
173 break;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700174 }
175
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700176 offset += block.size();
177
178 nfd::FaceStatus faceStatus(block);
179
180 std::cout << " faceid=" << faceStatus.getFaceId()
Junxiao Shi6e694322014-04-03 10:27:13 -0700181 << " remote=" << faceStatus.getRemoteUri()
182 << " local=" << faceStatus.getLocalUri()
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700183 << " counters={"
Junxiao Shi6e694322014-04-03 10:27:13 -0700184 << "in={" << faceStatus.getNInInterests() << "i "
185 << faceStatus.getNInDatas() << "d}"
186 << " out={" << faceStatus.getNOutInterests() << "i "
187 << faceStatus.getNOutDatas() << "d}"
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700188 << "}" << std::endl;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700189 }
190
191 if (m_needFibEnumerationRetrieval)
192 {
193 fetchFibEnumerationInformation();
194 }
195 }
196
197 void
198 fetchFaceStatusInformation()
199 {
200 m_buffer = make_shared<OBufferStream>();
201
202 Interest interest("/localhost/nfd/faces/list");
203 interest.setChildSelector(1);
204 interest.setMustBeFresh(true);
205
206 m_face.expressInterest(interest,
207 bind(&NfdStatus::fetchSegments, this, _2,
208 &NfdStatus::afterFetchedFaceStatusInformation),
209 bind(&NfdStatus::onTimeout, this));
210 }
211
212 void
213 afterFetchedFibEnumerationInformation()
214 {
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700215 std::cout << "FIB:" << std::endl;
216
217 ConstBufferPtr buf = m_buffer->buf();
218
219 Block block;
220 size_t offset = 0;
221 while (offset < buf->size())
jeraldabrahamb6dde382014-03-19 18:58:09 -0700222 {
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700223 bool ok = Block::fromBuffer(buf, offset, block);
224 if (!ok)
jeraldabrahamb6dde382014-03-19 18:58:09 -0700225 {
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700226 std::cerr << "ERROR: cannot decode FibEntry TLV" << std::endl;
227 break;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700228 }
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700229 offset += block.size();
230
231 nfd::FibEntry fibEntry(block);
232
233 std::cout << " " << fibEntry.getPrefix() << " nexthops={";
234 for (std::list<nfd::NextHopRecord>::const_iterator
235 nextHop = fibEntry.getNextHopRecords().begin();
236 nextHop != fibEntry.getNextHopRecords().end();
237 ++nextHop)
238 {
239 if (nextHop != fibEntry.getNextHopRecords().begin())
240 std::cout << ", ";
241 std::cout << "faceid=" << nextHop->getFaceId()
242 << " (cost=" << nextHop->getCost() << ")";
243 }
244 std::cout << "}" << std::endl;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700245 }
246 }
247
248 void
249 fetchFibEnumerationInformation()
250 {
251 m_buffer = make_shared<OBufferStream>();
252
253 Interest interest("/localhost/nfd/fib/list");
254 interest.setChildSelector(1);
255 interest.setMustBeFresh(true);
256 m_face.expressInterest(interest,
257 bind(&NfdStatus::fetchSegments, this, _2,
258 &NfdStatus::afterFetchedFibEnumerationInformation),
259 bind(&NfdStatus::onTimeout, this));
260 }
261
262 void
263 fetchInformation()
264 {
265 if (!m_needVersionRetrieval &&
266 !m_needFaceStatusRetrieval &&
267 !m_needFibEnumerationRetrieval)
268 {
269 enableVersionRetrieval();
270 enableFaceStatusRetrieval();
271 enableFibEnumerationRetrieval();
272 }
273
274 if (m_needVersionRetrieval)
275 {
276 fetchVersionInformation();
277 }
278 else if (m_needFaceStatusRetrieval)
279 {
280 fetchFaceStatusInformation();
281 }
282 else if (m_needFibEnumerationRetrieval)
283 {
284 fetchFibEnumerationInformation();
285 }
286
287 m_face.processEvents();
288 }
289
290private:
291 std::string m_toolName;
292 bool m_needVersionRetrieval;
293 bool m_needFaceStatusRetrieval;
294 bool m_needFibEnumerationRetrieval;
295 Face m_face;
296
297 shared_ptr<OBufferStream> m_buffer;
298};
299
300}
301
302int main( int argc, char* argv[] )
303{
304 int option;
305 ndn::NfdStatus nfdStatus (argv[0]);
306
307 while ((option = getopt(argc, argv, "hvfb")) != -1) {
308 switch (option) {
309 case 'h':
310 nfdStatus.usage();
Alexander Afanasyev60a7ba52014-03-23 11:23:06 -0700311 return 0;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700312 case 'v':
313 nfdStatus.enableVersionRetrieval();
314 break;
315 case 'f':
316 nfdStatus.enableFaceStatusRetrieval();
317 break;
318 case 'b':
319 nfdStatus.enableFibEnumerationRetrieval();
320 break;
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700321 default:
jeraldabrahamb6dde382014-03-19 18:58:09 -0700322 nfdStatus.usage();
323 return 1;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700324 }
325 }
326
327 try {
328 nfdStatus.fetchInformation();
329 }
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700330 catch (std::exception& e) {
jeraldabrahamb6dde382014-03-19 18:58:09 -0700331 std::cerr << "ERROR: " << e.what() << std::endl;
332 return 2;
333 }
334
335 return 0;
336}