blob: a3033a6277cc5ea6c290c3078b1fa363c75efbd8 [file] [log] [blame]
Junxiao Shi38f4ce92016-08-04 10:01:52 +00001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014-2016, 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.
10 *
11 * 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
26#include "version.hpp"
27#include <ndn-cxx/security/validator-null.hpp>
28
29#include <boost/program_options/options_description.hpp>
30#include <boost/program_options/variables_map.hpp>
31#include <boost/program_options/parsers.hpp>
32
33#include "status-report.hpp"
34#include "forwarder-general-module.hpp"
35#include "channel-module.hpp"
36#include "face-module.hpp"
37#include "fib-module.hpp"
38#include "rib-module.hpp"
39#include "strategy-choice-module.hpp"
40
41namespace nfd {
42namespace tools {
43namespace nfd_status {
44
45enum class OutputFormat
46{
47 XML = 1,
48 TEXT = 2
49};
50
51struct Options
52{
53 OutputFormat output = OutputFormat::TEXT;
54 bool wantForwarderGeneral = false;
55 bool wantChannels = false;
56 bool wantFaces = false;
57 bool wantFib = false;
58 bool wantRib = false;
59 bool wantStrategyChoice = false;
60};
61
62static void
63showUsage(std::ostream& os, const boost::program_options::options_description& cmdOptions)
64{
65 os << "Usage: nfd-status [options]\n\n"
66 << "Show NFD version and status information.\n\n"
67 << cmdOptions;
68}
69
70/** \brief parse command line, and show usage if necessary
71 * \return if first item is -1, caller should retrieve and display StatusReport;
72 * otherwise, caller should immediately exit with the specified exit code
73 */
74static std::tuple<int, Options>
75parseCommandLine(int argc, const char* const* argv)
76{
77 Options options;
78
79 namespace po = boost::program_options;
80 po::options_description cmdOptions("Options");
81 cmdOptions.add_options()
82 ("help,h", "print this help message")
83 ("version,V", "show program version")
84 ("general,v", po::bool_switch(&options.wantForwarderGeneral), "show general status")
85 ("channels,c", po::bool_switch(&options.wantChannels), "show channels")
86 ("faces,f", po::bool_switch(&options.wantFaces), "show faces")
87 ("fib,b", po::bool_switch(&options.wantFib), "show FIB entries")
88 ("rib,r", po::bool_switch(&options.wantRib), "show RIB routes")
89 ("sc,s", po::bool_switch(&options.wantStrategyChoice), "show strategy choice entries")
90 ("xml,x", "output as XML instead of text (implies -vcfbrs)");
91 po::variables_map vm;
92 try {
93 po::store(po::parse_command_line(argc, argv, cmdOptions), vm);
94 }
95 catch (const po::error& e) {
96 std::cerr << e.what() << "\n";
97 showUsage(std::cerr, cmdOptions);
98 return std::make_tuple(2, options);
99 }
100 po::notify(vm);
101
102 if (vm.count("help") > 0) {
103 showUsage(std::cout, cmdOptions);
104 return std::make_tuple(0, options);
105 }
106 if (vm.count("version") > 0) {
107 std::cout << "nfd-status " << NFD_VERSION_BUILD_STRING << "\n";
108 return std::make_tuple(0, options);
109 }
110
111 if (vm.count("xml") > 0) {
112 options.output = OutputFormat::XML;
113 }
114 if (options.output == OutputFormat::XML ||
115 (!options.wantForwarderGeneral && !options.wantChannels && !options.wantFaces &&
116 !options.wantFib && !options.wantRib && !options.wantStrategyChoice)) {
117 options.wantForwarderGeneral = options.wantChannels = options.wantFaces =
118 options.wantFib = options.wantRib = options.wantStrategyChoice = true;
119 }
120
121 return std::make_tuple(-1, options);
122}
123
124static int
125main(int argc, char** argv)
126{
127 int exitCode = -1;
128 Options options;
129 std::tie(exitCode, options) = parseCommandLine(argc, argv);
130 if (exitCode >= 0) {
131 return exitCode;
132 }
133
134 Face face;
135 KeyChain keyChain;
136 unique_ptr<Validator> validator = make_unique<ndn::ValidatorNull>();
137 CommandOptions ctrlOptions;
138
139 StatusReport report;
140
141 if (options.wantForwarderGeneral) {
142 auto nfdIdCollector = make_unique<NfdIdCollector>(std::move(validator));
143 auto forwarderGeneralModule = make_unique<ForwarderGeneralModule>();
144 forwarderGeneralModule->setNfdIdCollector(*nfdIdCollector);
145 report.sections.push_back(std::move(forwarderGeneralModule));
146 validator = std::move(nfdIdCollector);
147 }
148
149 if (options.wantChannels) {
150 report.sections.push_back(make_unique<ChannelModule>());
151 }
152
153 if (options.wantFaces) {
154 report.sections.push_back(make_unique<FaceModule>());
155 }
156
157 if (options.wantFib) {
158 report.sections.push_back(make_unique<FibModule>());
159 }
160
161 if (options.wantRib) {
162 report.sections.push_back(make_unique<RibModule>());
163 }
164
165 if (options.wantStrategyChoice) {
166 report.sections.push_back(make_unique<StrategyChoiceModule>());
167 }
168
169 uint32_t code = report.collect(face, keyChain, *validator, ctrlOptions);
170 if (code != 0) {
171 // Give a simple error code for end user.
172 // Technical support personnel:
173 // 1. get the exact command from end user
174 // 2. code div 1000000 is zero-based section index
175 // 3. code mod 1000000 is a Controller.fetch error code
176 std::cerr << "Error while collecting status report (" << code << ").\n";
177 return 1;
178 }
179
180 switch (options.output) {
181 case OutputFormat::XML:
182 report.formatXml(std::cout);
183 break;
184 case OutputFormat::TEXT:
185 report.formatText(std::cout);
186 break;
187 }
188 return 0;
189}
190
191} // namespace nfd_status
192} // namespace tools
193} // namespace nfd
194
195int
196main(int argc, char** argv)
197{
198 return nfd::tools::nfd_status::main(argc, argv);
199}