/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /** * Copyright (C) 2014 Named Data Networking Project * See COPYING for copyright and distribution information. */ #include "nfdc.hpp" #include #include #include #include void usage(const char* programName) { std::cout << "Usage:\n" << programName << " [-h] COMMAND\n" " -h print usage and exit\n" "\n" " COMMAND can be one of following:\n" " add-nexthop []\n" " Add a nexthop to a FIB entry\n" " remove-nexthop \n" " Remove a nexthop from a FIB entry\n" " create \n" " Create a face in one of the following formats:\n" " UDP unicast: udp[4|6]://[:]\n" " TCP: tcp[4|6]://[:] \n" " destroy \n" " Destroy a face\n" " set-strategy \n" " Set the strategy for a namespace \n" " unset-strategy \n" " Unset the strategy for a namespace \n" << std::endl; } namespace nfdc { Nfdc::Nfdc(ndn::Face& face) : m_controller(face) { } Nfdc::~Nfdc() { } bool Nfdc::dispatch(const std::string& command, const char* commandOptions[], int nOptions) { if (command == "add-nexthop") { if (nOptions == 2) fibAddNextHop(commandOptions, false); else if (nOptions == 3) fibAddNextHop(commandOptions, true); else return false; } else if (command == "remove-nexthop") { if (nOptions != 2) return false; fibRemoveNextHop(commandOptions); } else if (command == "create") { if (nOptions != 1) return false; faceCreate(commandOptions); } else if (command == "destroy") { if (nOptions != 1) return false; faceDestroy(commandOptions); } else if (command == "set-strategy") { if (nOptions != 2) return false; strategyChoiceSet(commandOptions); } else if (command == "unset-strategy") { if (nOptions != 1) return false; strategyChoiceUnset(commandOptions); } else usage(m_programName); return true; } void Nfdc::fibAddNextHop(const char* commandOptions[], bool hasCost) { const std::string& name = commandOptions[0]; const int faceId = boost::lexical_cast(commandOptions[1]); ControlParameters parameters; parameters .setName(name) .setFaceId(faceId); if (hasCost) { const uint64_t cost = boost::lexical_cast(commandOptions[2]); parameters.setCost(cost); } m_controller.start( parameters, bind(&Nfdc::onSuccess, this, _1, "Nexthop insertion succeeded"), bind(&Nfdc::onError, this, _1, _2, "Nexthop insertion failed")); } void Nfdc::fibRemoveNextHop(const char* commandOptions[]) { const std::string& name = commandOptions[0]; const int faceId = boost::lexical_cast(commandOptions[1]); ControlParameters parameters; parameters .setName(name) .setFaceId(faceId); m_controller.start( parameters, bind(&Nfdc::onSuccess, this, _1, "Nexthop removal succeeded"), bind(&Nfdc::onError, this, _1, _2, "Nexthop removal failed")); } namespace { inline bool isValidUri(const std::string& input) { // an extended regex to support the validation of uri structure // boost::regex e("^[a-z0-9]+-?+[a-z0-9]+\\:\\/\\/.*"); boost::regex e("^[a-z0-9]+\\:.*"); return boost::regex_match(input, e); } } // anonymous namespace void Nfdc::faceCreate(const char* commandOptions[]) { const std::string& uri = commandOptions[0]; if (!isValidUri(uri)) throw Error("invalid uri format"); ControlParameters parameters; parameters .setUri(uri); m_controller.start( parameters, bind(&Nfdc::onSuccess, this, _1, "Face creation succeeded"), bind(&Nfdc::onError, this, _1, _2, "Face creation failed")); } void Nfdc::faceDestroy(const char* commandOptions[]) { const int faceId = boost::lexical_cast(commandOptions[0]); ControlParameters parameters; parameters .setFaceId(faceId); m_controller.start( parameters, bind(&Nfdc::onSuccess, this, _1, "Face destroy succeeded"), bind(&Nfdc::onError, this, _1, _2, "Face destroy failed")); } void Nfdc::strategyChoiceSet(const char* commandOptions[]) { const std::string& name = commandOptions[0]; const std::string& strategy = commandOptions[1]; ControlParameters parameters; parameters .setName(name) .setStrategy(strategy); m_controller.start( parameters, bind(&Nfdc::onSuccess, this, _1, "Successfully set strategy choice"), bind(&Nfdc::onError, this, _1, _2, "Failed to set strategy choice")); } void Nfdc::strategyChoiceUnset(const char* commandOptions[]) { const std::string& name = commandOptions[0]; ControlParameters parameters; parameters .setName(name); m_controller.start( parameters, bind(&Nfdc::onSuccess, this, _1, "Successfully unset strategy choice"), bind(&Nfdc::onError, this, _1, _2, "Failed to unset strategy choice")); } void Nfdc::onSuccess(const ControlParameters& parameters, const std::string& message) { std::cout << message << ": " << parameters << std::endl; } void Nfdc::onError(uint32_t code, const std::string& error, const std::string& message) { std::ostringstream os; os << message << ": " << error << " (code: " << code << ")"; throw Error(os.str()); } } // namespace nfdc int main(int argc, char** argv) { ndn::Face face; nfdc::Nfdc p(face); p.m_programName = argv[0]; int opt; while ((opt = getopt(argc, argv, "h")) != -1) { switch (opt) { case 'h': usage(p.m_programName); return 0; default: usage(p.m_programName); return 1; } } if (argc == optind) { usage(p.m_programName); return 1; } try { bool isOk = p.dispatch(argv[optind], const_cast(argv + optind + 1), argc - optind - 1); if (!isOk) { usage(p.m_programName); return 1; } face.processEvents(); } catch (const std::exception& e) { std::cerr << "ERROR: " << e.what() << std::endl; return 2; } return 0; }