blob: 32a008cd654a3a493f33e68516d4e320fdba5141 [file] [log] [blame]
Vince Lehmanc439d662015-04-27 10:56:00 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Ashlesh Gawande0421bc62020-05-08 20:42:19 -07002/*
Junxiao Shi153fbc12024-01-09 23:37:23 +00003 * Copyright (c) 2014-2024, The University of Memphis,
Vince Lehmanc439d662015-04-27 10:56:00 -05004 * Regents of the University of California,
5 * Arizona Board of Regents.
6 *
7 * This file is part of NLSR (Named-data Link State Routing).
8 * See AUTHORS.md for complete list of NLSR authors and contributors.
9 *
10 * NLSR is free software: you can redistribute it and/or modify it under the terms
11 * of the GNU General Public License as published by the Free Software Foundation,
12 * either version 3 of the License, or (at your option) any later version.
13 *
14 * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
15 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 * PURPOSE. See the GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Ashlesh Gawande0421bc62020-05-08 20:42:19 -070020 */
Vince Lehmanc439d662015-04-27 10:56:00 -050021
22#include "nlsrc.hpp"
23
Junxiao Shia3a63972022-01-24 02:03:41 +000024#include "config.hpp"
Vince Lehmanc439d662015-04-27 10:56:00 -050025#include "version.hpp"
laqinfan35731852017-08-08 06:17:39 -050026#include "src/publisher/dataset-interest-handler.hpp"
Vince Lehmanc439d662015-04-27 10:56:00 -050027
Vince Lehmanc439d662015-04-27 10:56:00 -050028#include <ndn-cxx/data.hpp>
Vince Lehmanc439d662015-04-27 10:56:00 -050029#include <ndn-cxx/encoding/block.hpp>
Ashlesh Gawande30d96e42021-03-21 19:15:33 -070030#include <ndn-cxx/face.hpp>
31#include <ndn-cxx/interest.hpp>
Junxiao Shi3e5120c2016-09-10 16:58:34 +000032#include <ndn-cxx/mgmt/nfd/control-parameters.hpp>
33#include <ndn-cxx/mgmt/nfd/control-response.hpp>
Davide Pesavento6184c202021-05-17 02:28:03 -040034#include <ndn-cxx/security/interest-signer.hpp>
Ashlesh Gawande30d96e42021-03-21 19:15:33 -070035#include <ndn-cxx/security/key-chain.hpp>
36#include <ndn-cxx/security/signing-helpers.hpp>
Junxiao Shia3a63972022-01-24 02:03:41 +000037#include <ndn-cxx/security/validator-config.hpp>
38#include <ndn-cxx/security/validator-null.hpp>
Ashlesh Gawande30d96e42021-03-21 19:15:33 -070039#include <ndn-cxx/util/segment-fetcher.hpp>
Vince Lehmanc439d662015-04-27 10:56:00 -050040
Junxiao Shia3a63972022-01-24 02:03:41 +000041#include <boost/algorithm/string/replace.hpp>
42#include <boost/property_tree/info_parser.hpp>
43
Vince Lehmanc439d662015-04-27 10:56:00 -050044#include <iostream>
45
46namespace nlsrc {
47
Junxiao Shia3a63972022-01-24 02:03:41 +000048const ndn::Name LOCALHOST_PREFIX("/localhost");
49const ndn::PartialName LSDB_SUFFIX("nlsr/lsdb");
50const ndn::PartialName NAME_UPDATE_SUFFIX("nlsr/prefix-update");
51const ndn::PartialName RT_SUFFIX("nlsr/routing-table");
Vince Lehmanc439d662015-04-27 10:56:00 -050052
Junxiao Shia3a63972022-01-24 02:03:41 +000053const uint32_t ERROR_CODE_TIMEOUT = 10060;
54const uint32_t RESPONSE_CODE_SUCCESS = 200;
Junxiao Shif7ea1502023-06-23 04:30:19 +000055const uint32_t RESPONSE_CODE_NO_EFFECT = 204;
Junxiao Shia3a63972022-01-24 02:03:41 +000056const uint32_t RESPONSE_CODE_SAVE_OR_DELETE = 205;
laqinfan35731852017-08-08 06:17:39 -050057
Junxiao Shia3a63972022-01-24 02:03:41 +000058Nlsrc::Nlsrc(std::string programName, ndn::Face& face)
59 : m_programName(std::move(programName))
60 , m_routerPrefix(LOCALHOST_PREFIX)
61 , m_face(face)
Vince Lehmanc439d662015-04-27 10:56:00 -050062{
Junxiao Shia3a63972022-01-24 02:03:41 +000063 disableValidator();
Vince Lehmanc439d662015-04-27 10:56:00 -050064}
65
66void
Junxiao Shia3a63972022-01-24 02:03:41 +000067Nlsrc::printUsage() const
Vince Lehmanc439d662015-04-27 10:56:00 -050068{
Junxiao Shif7ea1502023-06-23 04:30:19 +000069 const std::string help(R"EOT(Usage:
Junxiao Shia3a63972022-01-24 02:03:41 +000070@NLSRC@ [-h | -V]
71@NLSRC@ [-R <router prefix> [-c <nlsr.conf path> | -k]] COMMAND [<Command Options>]
72 -h print usage and exit
73 -V print version and exit
74 -R target a remote NLSR instance
75 -c verify response with nlsr.conf security.validator policy
76 -k do not verify response (insecure)
77
78 COMMAND can be one of the following:
79 lsdb
80 display NLSR lsdb status
81 routing
82 display routing table status
83 status
84 display all NLSR status (lsdb & routingtable)
85 advertise <name>
86 advertise a name prefix through NLSR
87 advertise <name> save
88 advertise and save the name prefix to the conf file
89 withdraw <name>
90 remove a name prefix advertised through NLSR
91 withdraw <name> delete
92 withdraw and delete the name prefix from the conf file
93)EOT");
Junxiao Shif7ea1502023-06-23 04:30:19 +000094 boost::algorithm::replace_all_copy(std::ostream_iterator<char>(std::cout),
95 help, "@NLSRC@", m_programName);
Junxiao Shia3a63972022-01-24 02:03:41 +000096}
97
98void
99Nlsrc::setRouterPrefix(ndn::Name prefix)
100{
101 m_routerPrefix = std::move(prefix);
102}
103
104void
105Nlsrc::disableValidator()
106{
107 m_validator.reset(new ndn::security::ValidatorNull());
108}
109
110bool
111Nlsrc::enableValidator(const std::string& filename)
112{
113 using namespace boost::property_tree;
114 ptree validatorConfig;
115 try {
116 ptree config;
117 read_info(filename, config);
118 validatorConfig = config.get_child("security.validator");
119 }
120 catch (const ptree_error& e) {
121 std::cerr << "Failed to parse configuration file '" << filename
122 << "': " << e.what() << std::endl;
123 return false;
124 }
125
126 auto validator = std::make_unique<ndn::security::ValidatorConfig>(m_face);
127 try {
128 validator->load(validatorConfig, filename);
129 }
130 catch (const ndn::security::validator_config::Error& e) {
131 std::cerr << "Failed to load validator config from '" << filename
132 << "' security.validator section: " << e.what() << std::endl;
133 return false;
134 }
135
136 m_validator = std::move(validator);
137 return true;
Vince Lehmanc439d662015-04-27 10:56:00 -0500138}
139
140void
laqinfan35731852017-08-08 06:17:39 -0500141Nlsrc::getStatus(const std::string& command)
Vince Lehmanc439d662015-04-27 10:56:00 -0500142{
laqinfan35731852017-08-08 06:17:39 -0500143 if (command == "lsdb") {
144 m_fetchSteps.push_back(std::bind(&Nlsrc::fetchAdjacencyLsas, this));
145 m_fetchSteps.push_back(std::bind(&Nlsrc::fetchCoordinateLsas, this));
146 m_fetchSteps.push_back(std::bind(&Nlsrc::fetchNameLsas, this));
147 m_fetchSteps.push_back(std::bind(&Nlsrc::printLsdb, this));
148 }
149 else if (command == "routing") {
150 m_fetchSteps.push_back(std::bind(&Nlsrc::fetchRtables, this));
151 m_fetchSteps.push_back(std::bind(&Nlsrc::printRT, this));
152 }
Junxiao Shia3a63972022-01-24 02:03:41 +0000153 else if (command == "status") {
laqinfan35731852017-08-08 06:17:39 -0500154 m_fetchSteps.push_back(std::bind(&Nlsrc::fetchAdjacencyLsas, this));
155 m_fetchSteps.push_back(std::bind(&Nlsrc::fetchCoordinateLsas, this));
156 m_fetchSteps.push_back(std::bind(&Nlsrc::fetchNameLsas, this));
157 m_fetchSteps.push_back(std::bind(&Nlsrc::fetchRtables, this));
158 m_fetchSteps.push_back(std::bind(&Nlsrc::printAll, this));
159 }
Vince Lehmanc439d662015-04-27 10:56:00 -0500160 runNextStep();
161}
162
163bool
Junxiao Shia3a63972022-01-24 02:03:41 +0000164Nlsrc::dispatch(ndn::span<std::string> subcommand)
Vince Lehmanc439d662015-04-27 10:56:00 -0500165{
Junxiao Shia3a63972022-01-24 02:03:41 +0000166 if (subcommand.size() == 0) {
167 return false;
Vince Lehmanc439d662015-04-27 10:56:00 -0500168 }
169
Junxiao Shia3a63972022-01-24 02:03:41 +0000170 if (subcommand[0] == "advertise") {
171 switch (subcommand.size()) {
172 case 2:
173 advertiseName(subcommand[1], false);
174 return true;
175 case 3:
176 if (subcommand[2] != "save") {
177 return false;
178 }
179 advertiseName(subcommand[1], true);
180 return true;
181 }
182 return false;
183 }
184
185 if (subcommand[0] == "withdraw") {
186 switch (subcommand.size()) {
187 case 2:
188 withdrawName(subcommand[1], false);
189 return true;
190 case 3:
191 if (subcommand[2] != "delete") {
192 return false;
193 }
194 withdrawName(subcommand[1], true);
195 return true;
196 }
197 return false;
198 }
199
200 if (subcommand[0] == "lsdb" || subcommand[0] == "routing" || subcommand[0] == "status") {
201 if (subcommand.size() != 1) {
202 return false;
203 }
204 getStatus(subcommand[0]);
205 return true;
206 }
Vince Lehmanc439d662015-04-27 10:56:00 -0500207 return false;
208}
209
210void
211Nlsrc::runNextStep()
212{
213 if (m_fetchSteps.empty()) {
214 return;
215 }
216
217 std::function<void()> nextStep = m_fetchSteps.front();
218 m_fetchSteps.pop_front();
219
220 nextStep();
221}
222
223void
Junxiao Shia3a63972022-01-24 02:03:41 +0000224Nlsrc::advertiseName(ndn::Name name, bool wantSave)
Vince Lehmanc439d662015-04-27 10:56:00 -0500225{
Junxiao Shia3a63972022-01-24 02:03:41 +0000226 std::string info = (wantSave ? "(Save: " : "(Advertise: ") + name.toUri() + ")";
Saurab Dulal7526cee2018-01-31 18:14:10 +0000227 ndn::Name::Component verb("advertise");
Junxiao Shia3a63972022-01-24 02:03:41 +0000228 sendNamePrefixUpdate(name, verb, info, wantSave);
Vince Lehmanc439d662015-04-27 10:56:00 -0500229}
230
231void
Junxiao Shia3a63972022-01-24 02:03:41 +0000232Nlsrc::withdrawName(ndn::Name name, bool wantDelete)
Vince Lehmanc439d662015-04-27 10:56:00 -0500233{
Junxiao Shia3a63972022-01-24 02:03:41 +0000234 std::string info = (wantDelete ? "(Delete: " : "(Withdraw: ") + name.toUri() + ")";
Saurab Dulal7526cee2018-01-31 18:14:10 +0000235 ndn::Name::Component verb("withdraw");
Junxiao Shia3a63972022-01-24 02:03:41 +0000236 sendNamePrefixUpdate(name, verb, info, wantDelete);
Vince Lehmanc439d662015-04-27 10:56:00 -0500237}
238
239void
240Nlsrc::sendNamePrefixUpdate(const ndn::Name& name,
241 const ndn::Name::Component& verb,
Saurab Dulal7526cee2018-01-31 18:14:10 +0000242 const std::string& info,
243 bool flag)
Vince Lehmanc439d662015-04-27 10:56:00 -0500244{
245 ndn::nfd::ControlParameters parameters;
246 parameters.setName(name);
Saurab Dulal7526cee2018-01-31 18:14:10 +0000247 if (flag) {
248 parameters.setFlags(1);
249 }
Vince Lehmanc439d662015-04-27 10:56:00 -0500250
Junxiao Shia3a63972022-01-24 02:03:41 +0000251 auto paramWire = parameters.wireEncode();
252 ndn::Name commandName = m_routerPrefix;
253 commandName.append(NAME_UPDATE_SUFFIX);
Vince Lehmanc439d662015-04-27 10:56:00 -0500254 commandName.append(verb);
Junxiao Shia3a63972022-01-24 02:03:41 +0000255 commandName.append(paramWire.begin(), paramWire.end());
Vince Lehmanc439d662015-04-27 10:56:00 -0500256
Davide Pesavento6184c202021-05-17 02:28:03 -0400257 ndn::security::InterestSigner signer(m_keyChain);
258 auto commandInterest = signer.makeCommandInterest(commandName,
259 ndn::security::signingByIdentity(m_keyChain.getPib().getDefaultIdentity()));
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500260 commandInterest.setMustBeFresh(true);
261
262 m_face.expressInterest(commandInterest,
Vince Lehmanc439d662015-04-27 10:56:00 -0500263 std::bind(&Nlsrc::onControlResponse, this, info, _2),
Alexander Afanasyev1de901f2017-03-09 12:43:57 -0800264 std::bind(&Nlsrc::onTimeout, this, ERROR_CODE_TIMEOUT, "Nack"),
Vince Lehmanc439d662015-04-27 10:56:00 -0500265 std::bind(&Nlsrc::onTimeout, this, ERROR_CODE_TIMEOUT, "Timeout"));
266}
267
268void
269Nlsrc::onControlResponse(const std::string& info, const ndn::Data& data)
270{
Vince Lehmand33e5bc2015-06-22 15:27:50 -0500271 if (data.getMetaInfo().getType() == ndn::tlv::ContentType_Nack) {
272 std::cerr << "ERROR: Run-time advertise/withdraw disabled" << std::endl;
273 return;
274 }
275
Vince Lehmanc439d662015-04-27 10:56:00 -0500276 ndn::nfd::ControlResponse response;
277
278 try {
279 response.wireDecode(data.getContent().blockFromValue());
280 }
281 catch (const std::exception& e) {
282 std::cerr << "ERROR: Control response decoding error" << std::endl;
Junxiao Shif7ea1502023-06-23 04:30:19 +0000283 m_exitCode = 1;
Vince Lehmanc439d662015-04-27 10:56:00 -0500284 return;
285 }
286
287 uint32_t code = response.getCode();
288
Saurab Dulal7526cee2018-01-31 18:14:10 +0000289 if (code != RESPONSE_CODE_SUCCESS && code != RESPONSE_CODE_SAVE_OR_DELETE) {
Saurab Dulal7526cee2018-01-31 18:14:10 +0000290 std::cerr << response.getText() << std::endl;
Vince Lehmanc439d662015-04-27 10:56:00 -0500291 std::cerr << "Name prefix update error (code: " << code << ")" << std::endl;
Junxiao Shif7ea1502023-06-23 04:30:19 +0000292 m_exitCode = code == RESPONSE_CODE_NO_EFFECT ? 0 : 1;
Vince Lehmanc439d662015-04-27 10:56:00 -0500293 return;
294 }
295
296 std::cout << "Applied Name prefix update successfully: " << info << std::endl;
Junxiao Shif7ea1502023-06-23 04:30:19 +0000297 m_exitCode = 0;
Vince Lehmanc439d662015-04-27 10:56:00 -0500298}
299
300void
301Nlsrc::fetchAdjacencyLsas()
302{
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800303 fetchFromLsdb<nlsr::AdjLsa>(nlsr::dataset::ADJACENCY_COMPONENT,
304 std::bind(&Nlsrc::recordLsa, this, _1));
Vince Lehmanc439d662015-04-27 10:56:00 -0500305}
306
307void
308Nlsrc::fetchCoordinateLsas()
309{
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800310 fetchFromLsdb<nlsr::CoordinateLsa>(nlsr::dataset::COORDINATE_COMPONENT,
311 std::bind(&Nlsrc::recordLsa, this, _1));
Vince Lehmanc439d662015-04-27 10:56:00 -0500312}
313
314void
315Nlsrc::fetchNameLsas()
316{
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800317 fetchFromLsdb<nlsr::NameLsa>(nlsr::dataset::NAME_COMPONENT,
318 std::bind(&Nlsrc::recordLsa, this, _1));
Vince Lehmanc439d662015-04-27 10:56:00 -0500319}
320
laqinfan35731852017-08-08 06:17:39 -0500321void
322Nlsrc::fetchRtables()
323{
Ashlesh Gawande0af46272020-12-12 16:45:13 -0500324 fetchFromRt<nlsr::RoutingTableStatus>([this] (const auto& rts) { this->recordRtable(rts); });
laqinfan35731852017-08-08 06:17:39 -0500325}
326
Junxiao Shia3a63972022-01-24 02:03:41 +0000327template<class T>
Vince Lehmanc439d662015-04-27 10:56:00 -0500328void
329Nlsrc::fetchFromLsdb(const ndn::Name::Component& datasetType,
330 const std::function<void(const T&)>& recordLsa)
331{
Junxiao Shia3a63972022-01-24 02:03:41 +0000332 auto name = m_routerPrefix;
333 name.append(LSDB_SUFFIX);
334 name.append(datasetType);
335 ndn::Interest interest(name);
Vince Lehmanc439d662015-04-27 10:56:00 -0500336
Junxiao Shi43f37a02023-08-09 00:09:00 +0000337 auto fetcher = ndn::SegmentFetcher::start(m_face, interest, *m_validator);
Ashlesh Gawande05cb7282018-08-30 14:39:41 -0500338 fetcher->onComplete.connect(std::bind(&Nlsrc::onFetchSuccess<T>, this, _1, recordLsa));
339 fetcher->onError.connect(std::bind(&Nlsrc::onTimeout, this, _1, _2));
Vince Lehmanc439d662015-04-27 10:56:00 -0500340}
341
Ashlesh Gawande57a87172020-05-09 19:47:06 -0700342void
343Nlsrc::recordLsa(const nlsr::Lsa& lsa)
344{
345 Router& router = m_routers.emplace(lsa.getOriginRouter(), Router()).first->second;
Junxiao Shi153fbc12024-01-09 23:37:23 +0000346 auto lsaString = boost::lexical_cast<std::string>(lsa);
Ashlesh Gawande57a87172020-05-09 19:47:06 -0700347
348 if (lsa.getType() == nlsr::Lsa::Type::ADJACENCY) {
Junxiao Shi153fbc12024-01-09 23:37:23 +0000349 router.adjacencyLsaString = lsaString;
Ashlesh Gawande57a87172020-05-09 19:47:06 -0700350 }
351 else if (lsa.getType() == nlsr::Lsa::Type::COORDINATE) {
Junxiao Shi153fbc12024-01-09 23:37:23 +0000352 router.coordinateLsaString = lsaString;
Ashlesh Gawande57a87172020-05-09 19:47:06 -0700353 }
354 else if (lsa.getType() == nlsr::Lsa::Type::NAME) {
Junxiao Shi153fbc12024-01-09 23:37:23 +0000355 router.nameLsaString = lsaString;
Ashlesh Gawande57a87172020-05-09 19:47:06 -0700356 }
357}
358
Junxiao Shia3a63972022-01-24 02:03:41 +0000359template<class T>
Vince Lehmanc439d662015-04-27 10:56:00 -0500360void
laqinfan35731852017-08-08 06:17:39 -0500361Nlsrc::fetchFromRt(const std::function<void(const T&)>& recordDataset)
362{
Junxiao Shia3a63972022-01-24 02:03:41 +0000363 auto name = m_routerPrefix;
364 name.append(RT_SUFFIX);
365 ndn::Interest interest(name);
laqinfan35731852017-08-08 06:17:39 -0500366
Junxiao Shi43f37a02023-08-09 00:09:00 +0000367 auto fetcher = ndn::SegmentFetcher::start(m_face, interest, *m_validator);
Ashlesh Gawande05cb7282018-08-30 14:39:41 -0500368 fetcher->onComplete.connect(std::bind(&Nlsrc::onFetchSuccess<T>, this, _1, recordDataset));
369 fetcher->onError.connect(std::bind(&Nlsrc::onTimeout, this, _1, _2));
laqinfan35731852017-08-08 06:17:39 -0500370}
371
Junxiao Shia3a63972022-01-24 02:03:41 +0000372template<class T>
laqinfan35731852017-08-08 06:17:39 -0500373void
Davide Pesaventoc1d0e8e2022-06-15 14:26:02 -0400374Nlsrc::onFetchSuccess(const ndn::ConstBufferPtr& buf,
laqinfan35731852017-08-08 06:17:39 -0500375 const std::function<void(const T&)>& recordDataset)
Vince Lehmanc439d662015-04-27 10:56:00 -0500376{
Vince Lehmanc439d662015-04-27 10:56:00 -0500377 size_t offset = 0;
Davide Pesaventoc1d0e8e2022-06-15 14:26:02 -0400378 while (offset < buf->size()) {
379 auto [isOk, block] = ndn::Block::fromBuffer(buf, offset);
Vince Lehmanc439d662015-04-27 10:56:00 -0500380
381 if (!isOk) {
382 std::cerr << "ERROR: cannot decode LSA TLV" << std::endl;
383 break;
384 }
385
386 offset += block.size();
387
Davide Pesaventoc1d0e8e2022-06-15 14:26:02 -0400388 T dataset(block);
389 recordDataset(dataset);
Vince Lehmanc439d662015-04-27 10:56:00 -0500390 }
391
392 runNextStep();
393}
394
395void
396Nlsrc::onTimeout(uint32_t errorCode, const std::string& error)
397{
398 std::cerr << "Request timed out (code: " << errorCode
399 << ", error: " << error << ")" << std::endl;
Junxiao Shif7ea1502023-06-23 04:30:19 +0000400 m_exitCode = 1;
Vince Lehmanc439d662015-04-27 10:56:00 -0500401}
402
Vince Lehmanc439d662015-04-27 10:56:00 -0500403void
Ashlesh Gawande0421bc62020-05-08 20:42:19 -0700404Nlsrc::recordRtable(const nlsr::RoutingTableStatus& rts)
laqinfan35731852017-08-08 06:17:39 -0500405{
laqinfan35731852017-08-08 06:17:39 -0500406 std::ostringstream os;
Ashlesh Gawande0421bc62020-05-08 20:42:19 -0700407 os << rts;
laqinfana073e2e2018-01-15 21:17:24 +0000408 m_rtString = os.str();
laqinfan35731852017-08-08 06:17:39 -0500409}
410
411void
Vince Lehmanc439d662015-04-27 10:56:00 -0500412Nlsrc::printLsdb()
413{
Vince Lehmanc439d662015-04-27 10:56:00 -0500414 std::cout << "LSDB:" << std::endl;
415
416 for (const auto& item : m_routers) {
417 std::cout << " OriginRouter: " << item.first << std::endl;
418 std::cout << std::endl;
419
420 const Router& router = item.second;
421
422 if (!router.adjacencyLsaString.empty()) {
423 std::cout << router.adjacencyLsaString << std::endl;
424 }
425
426 if (!router.coordinateLsaString.empty()) {
427 std::cout << router.coordinateLsaString << std::endl;
428 }
429
430 if (!router.nameLsaString.empty()) {
431 std::cout << router.nameLsaString << std::endl;
432 }
433 }
434}
435
laqinfan35731852017-08-08 06:17:39 -0500436void
437Nlsrc::printRT()
438{
laqinfana073e2e2018-01-15 21:17:24 +0000439 if (!m_rtString.empty()) {
Ashlesh Gawande0421bc62020-05-08 20:42:19 -0700440 std::cout << m_rtString;
laqinfana073e2e2018-01-15 21:17:24 +0000441 }
442 else {
443 std::cout << "Routing Table is not calculated yet" << std::endl;
laqinfan35731852017-08-08 06:17:39 -0500444 }
445}
446
447void
448Nlsrc::printAll()
449{
450 std::cout << "NLSR Status" << std::endl;
451 printLsdb();
452 printRT();
453}
454
Vince Lehmanc439d662015-04-27 10:56:00 -0500455} // namespace nlsrc
456
457////////////////////////////////////////////////////////////////////////////////
458////////////////////////////////////////////////////////////////////////////////
459
460int
461main(int argc, char** argv)
462{
463 ndn::Face face;
Junxiao Shia3a63972022-01-24 02:03:41 +0000464 nlsrc::Nlsrc nlsrc(argv[0], face);
Vince Lehmanc439d662015-04-27 10:56:00 -0500465
466 if (argc < 2) {
467 nlsrc.printUsage();
Junxiao Shif7ea1502023-06-23 04:30:19 +0000468 return 2;
Vince Lehmanc439d662015-04-27 10:56:00 -0500469 }
470
471 int opt;
Junxiao Shia3a63972022-01-24 02:03:41 +0000472 const char* confFile = DEFAULT_CONFIG_FILE;
473 bool disableValidator = false;
474 while ((opt = ::getopt(argc, argv, "hVR:c:k")) != -1) {
Vince Lehmanc439d662015-04-27 10:56:00 -0500475 switch (opt) {
476 case 'h':
477 nlsrc.printUsage();
478 return 0;
479 case 'V':
480 std::cout << NLSR_VERSION_BUILD_STRING << std::endl;
481 return 0;
Junxiao Shia3a63972022-01-24 02:03:41 +0000482 case 'R':
483 nlsrc.setRouterPrefix(::optarg);
484 break;
485 case 'c':
486 confFile = ::optarg;
487 break;
488 case 'k':
489 disableValidator = true;
490 break;
Vince Lehmanc439d662015-04-27 10:56:00 -0500491 default:
492 nlsrc.printUsage();
Junxiao Shif7ea1502023-06-23 04:30:19 +0000493 return 2;
Vince Lehmanc439d662015-04-27 10:56:00 -0500494 }
495 }
496
497 if (argc == ::optind) {
498 nlsrc.printUsage();
Junxiao Shif7ea1502023-06-23 04:30:19 +0000499 return 2;
Vince Lehmanc439d662015-04-27 10:56:00 -0500500 }
501
Junxiao Shia3a63972022-01-24 02:03:41 +0000502 if (nlsrc.getRouterPrefix() != nlsrc::LOCALHOST_PREFIX && !disableValidator) {
503 if (!nlsrc.enableValidator(confFile)) {
504 return 1;
505 }
506 }
507
Junxiao Shif7ea1502023-06-23 04:30:19 +0000508 std::vector<std::string> subcommand(&argv[::optind], &argv[argc]);
Vince Lehmanc439d662015-04-27 10:56:00 -0500509 try {
Junxiao Shif7ea1502023-06-23 04:30:19 +0000510 bool isValidSyntax = nlsrc.dispatch(subcommand);
511 if (!isValidSyntax) {
Vince Lehmanc439d662015-04-27 10:56:00 -0500512 nlsrc.printUsage();
Junxiao Shif7ea1502023-06-23 04:30:19 +0000513 return 2;
Vince Lehmanc439d662015-04-27 10:56:00 -0500514 }
515
516 face.processEvents();
517 }
518 catch (const std::exception& e) {
519 std::cerr << "ERROR: " << e.what() << std::endl;
Junxiao Shif7ea1502023-06-23 04:30:19 +0000520 return 1;
Vince Lehmanc439d662015-04-27 10:56:00 -0500521 }
Junxiao Shif7ea1502023-06-23 04:30:19 +0000522 return nlsrc.getExitCode();
Alexander Afanasyevf9f39102015-12-01 17:43:40 -0800523}