From 5b7014737aa5f376174cc3d92e5e8856f5a13c11 Mon Sep 17 00:00:00 2001 From: /jedi/ Date: Sat, 6 Feb 2016 02:32:17 +0100 Subject: [PATCH] interactive shell wip --- Makefile | 3 +- src/Interactive.cpp | 33 ++++++++-- src/Interactive.h | 2 +- src/Packet.cpp | 4 +- src/Packet.h | 2 +- src/Program.cpp | 150 +++++++++++++++++++++++++++++++++++++------ src/Program.h | 2 + src/Socket.cpp | 58 +++++++++-------- src/Switch-Cmd.cpp | 31 +++++++++ src/Switch.h | 6 +- src/Types.h | 11 +++- src/lookup/input.lst | 10 +-- src/smrtlink.cpp | 126 ++++-------------------------------- 13 files changed, 261 insertions(+), 177 deletions(-) create mode 100644 src/Switch-Cmd.cpp diff --git a/Makefile b/Makefile index cd5dd04..a031fb5 100644 --- a/Makefile +++ b/Makefile @@ -15,8 +15,7 @@ $(BUILDDIR): $(TARGET): $(OBJECTS) - $(CC) $^ -o $(BUILDDIR)/$@ -lboost_filesystem -lboost_system -#-lboost_program_options + $(CC) $^ -o $(BUILDDIR)/$@ -lboost_filesystem -lboost_system -lreadline -lboost_program_options $(OBJECTS): $(BUILDDIR)/%.o : $(SOURCEDIR)/%.cpp $(CC) $(CFLAGS) $< -o $@ diff --git a/src/Interactive.cpp b/src/Interactive.cpp index 6875dc2..1c35283 100644 --- a/src/Interactive.cpp +++ b/src/Interactive.cpp @@ -7,7 +7,14 @@ #include #include +#include +#include +#include +#include +#include + +#include "Program.h" #include "Interactive.h" using namespace std; @@ -21,12 +28,28 @@ Interactive::~Interactive() { // TODO Auto-generated destructor stub } -int Interactive::run() { +int Interactive::loop() { string cmd; - while(cmd.compare("quit")){ - cout<< "smrtlink>" << flush; - cin >> cmd; - cout << cmd < v; + //vector vc; + //const char** argv; + //int argc; + + Program p = Program(); + p.init(); + + while (cmd.compare("quit")) { + cmd = readline("smrtlink> "); + add_history(cmd.c_str()); + v = boost::program_options::split_unix(cmd); + + //vc = vector(v.size()); + //std::transform(begin(v), end(v), begin(vc), [](std::string const &s) { return s.c_str(); }); + //argv = &vc[0]; + //argc = v.size(); + + p.run(v); + } return 0; } diff --git a/src/Interactive.h b/src/Interactive.h index 2bf41be..13547f3 100644 --- a/src/Interactive.h +++ b/src/Interactive.h @@ -12,7 +12,7 @@ class Interactive { public: Interactive(); virtual ~Interactive(); - int run(); + int loop(); }; #endif /* INTERACTIVE_H_ */ diff --git a/src/Packet.cpp b/src/Packet.cpp index 0e61bf7..9bcf06c 100644 --- a/src/Packet.cpp +++ b/src/Packet.cpp @@ -158,8 +158,8 @@ std::string Packet::opCodeToString() { return "SET"; case CONFIRM: return "CONFIRM"; - case RETURN: - return "RETURN"; + case REPLY: + return "REPLY"; default: return "NONE"; } diff --git a/src/Packet.h b/src/Packet.h index 2e04a2d..395c86d 100644 --- a/src/Packet.h +++ b/src/Packet.h @@ -18,7 +18,7 @@ static short sequenceId=0; class Packet { public: - enum OpCode {DISCOVERY, GET, RETURN, SET, CONFIRM, NONE}; + enum OpCode {DISCOVERY, GET, REPLY, SET, CONFIRM, NONE}; Packet(OpCode); static void encode(bytes&); bytes getBytes(); diff --git a/src/Program.cpp b/src/Program.cpp index 33f27d7..bc3c370 100644 --- a/src/Program.cpp +++ b/src/Program.cpp @@ -6,6 +6,9 @@ */ #include #include +#include +#include +#include #include "Constant.h" #include "Program.h" @@ -14,11 +17,117 @@ #include "Socket.h" #include "Switch.h" #include "Packet.h" +#include "Types.h" #include "lookup.h" #include "table.h" +using namespace smrtlink; using namespace std; +int Program::run(vector arg) { + int optind = 0; + std::vector vect; + std::map ll; + std::cmatch sm; + std::string cmd = arg[optind++]; + switch (caseArg(cmd.c_str())) { + case caseArg("reboot"): + if (!reboot()) + return 0; + fprintf(stderr, "Not yet implemented.\n"); + return 1; + break; + case caseArg("reset"): + if (!reset()) + return 0; + fprintf(stderr, "Not yet implemented.\n"); + return 1; + break; + case caseArg("save"): + if (!save()) + return 0; + fprintf(stderr, "Not yet implemented.\n"); + return 1; + break; + case caseArg("restore"): + if (!restore()) + return 0; + fprintf(stderr, "Not yet implemented.\n"); + return 1; + break; + case caseArg("flash"): + if (!flash()) + return 0; + fprintf(stderr, "Not yet implemented.\n"); + return 1; + break; + + case caseArg("list"): + if (!list()) + return 0; + break; + + case caseArg("sniff"): + if (!sniff()) + return 0; + break; + + case caseArg("encode"): + if (optind < arg.size()) { + std::string s(arg[optind]); + optind++; + if (encode(s)) + return 0; + } else { + fprintf(stderr, "Argument expected after encode\n"); + return 1; + } + break; + case caseArg("set"): + while (optind < arg.size()) { + if (regex_match(arg[optind].c_str(), sm, + std::regex("^([a-z]+)=(.*)$"))) { + if (!snd_lookup.exists(sm[1]) && !rcv_lookup.exists(sm[1])) { + cerr << "Unknown argument " << arg[optind] << endl; + return 1; + } + ll.insert(std::pair(sm[1], sm[2])); + } else { + cerr << "Invalid Syntax " << arg[optind] << endl; + return 1; + } + optind++; + } + if (!setProperty(ll)) + return 0; + fprintf(stderr, "Not yet implemented.\n"); + return 1; + break; + case caseArg("get"): + while (optind < arg.size()) { + if (regex_match(arg[optind].c_str(), sm, + std::regex("^([a-z]+)$"))) { + if (!snd_lookup.exists(sm[1]) && !rcv_lookup.exists(sm[1])) { + cerr << "Unknown argument " << arg[optind] << endl; + return 1; + } + vect.push_back(sm[1]); + } else { + cerr << "Invalid argument " << arg[optind] << endl; + return 1; + } + optind++; + } + if (!getProperty(vect)) + return 0; + break; + default: + printf("Unknown command: %s\n", cmd.c_str()); + return 1; + } + +} + int printHeader(Packet p) { if (options.flags.HEADER) { if (options.flags.HEX) { @@ -240,26 +349,27 @@ int Program::flash() { int Program::reboot() { try { - discover([this](Packet a) { - datasets d =a.getPayload(); - Switch sw = Switch(); - sw.parse(d); - cout <run(); } catch (exception& e) { cerr << "Exception: " << e.what() << "\n"; diff --git a/src/Program.h b/src/Program.h index 614047c..d8357a0 100644 --- a/src/Program.h +++ b/src/Program.h @@ -28,6 +28,8 @@ public: sock = std::make_shared(*io_service); } void init(); + int run(std::vector); + int list(); int sniff(); int encode(std::string); diff --git a/src/Socket.cpp b/src/Socket.cpp index 2d0e363..a864893 100644 --- a/src/Socket.cpp +++ b/src/Socket.cpp @@ -13,12 +13,15 @@ #include "Host.h" #include "Types.h" +#define SEND_F 1 +#define RECEIVE_F 2 + Socket::Socket(boost::asio::io_service& io_service) : send_socket_(io_service), receive_socket_(io_service), timer(io_service) { } //, resolver( io_service) void Socket::init(short dst_port, short src_port) { - if (initialized) + if (initialized == 3) return; if (options.flags.REVERSE) { @@ -27,7 +30,7 @@ void Socket::init(short dst_port, short src_port) { src_port = p; } - if (options.debug_level>=1) + if (options.debug_level >= 1) std::cout << "Local IP:\t" << local_ip << "\n"; wildcard_endpoint_ = boost::asio::ip::udp::endpoint( @@ -38,29 +41,7 @@ void Socket::init(short dst_port, short src_port) { boost::asio::ip::address_v4::from_string("255.255.255.255"), dst_port); - send_socket_.open(boost::asio::ip::udp::v4()); - send_socket_.set_option(boost::asio::socket_base::broadcast(true)); - send_socket_.set_option(boost::asio::socket_base::reuse_address(true)); - send_socket_.bind(local_endpoint_); - - receive_socket_.open(boost::asio::ip::udp::v4()); - receive_socket_.set_option(boost::asio::socket_base::broadcast(true)); - receive_socket_.set_option(boost::asio::socket_base::reuse_address(true)); - receive_socket_.bind(wildcard_endpoint_); - - if (options.timeout != 0) { - timer.expires_from_now( - boost::posix_time::milliseconds(options.timeout)); - timer.async_wait([this](const boost::system::error_code& error) - { - if (!error) - { - receive_socket_.close(); - } - }); - } - - initialized = 1; + initialized = 3; } void Socket::setHostIp(ipAddr ip) { @@ -68,6 +49,12 @@ void Socket::setHostIp(ipAddr ip) { } void Socket::send(Packet p) { + if (!send_socket_.is_open() || !(initialized&SEND_F)) { + send_socket_.open(boost::asio::ip::udp::v4()); + send_socket_.set_option(boost::asio::socket_base::broadcast(true)); + send_socket_.set_option(boost::asio::socket_base::reuse_address(true)); + send_socket_.bind(local_endpoint_); + } bytes data = p.getBytes(); p.encode(data); unsigned char * a = &data[0]; @@ -80,6 +67,25 @@ void Socket::send(Packet p) { } void Socket::listen() { + if (!receive_socket_.is_open() || !(initialized & RECEIVE_F)) { + receive_socket_.open(boost::asio::ip::udp::v4()); + receive_socket_.set_option(boost::asio::socket_base::broadcast(true)); + receive_socket_.set_option( + boost::asio::socket_base::reuse_address(true)); + receive_socket_.bind(wildcard_endpoint_); + } + if (options.timeout != 0) { + timer.expires_from_now( + boost::posix_time::milliseconds(options.timeout)); + timer.async_wait([this](const boost::system::error_code& error) + { + if (!error) + { + receive_socket_.close(); + initialized&=~RECEIVE_F; + } + }); + } data.resize(MAX_LENGTH); receive_socket_.async_receive_from(boost::asio::buffer(data, MAX_LENGTH), remote_endpoint_, @@ -92,7 +98,7 @@ void Socket::listen() { data.resize(bytes_recvd); Packet p = Packet(Packet::NONE); p.encode(data); - // std::cout << "err" << p.getErrorCode() < +#include "Types.h" +#include "Switch.h" +#include "Constant.h" +#include "table.h" + +using namespace smrtlink; +using namespace std; + +int Switch::set(pair str) { + + return 0; +} + +std::string Switch::get(std::string str) { + std::string ret; + switch (caseArg(str.c_str())) { + case caseArg("ip"): + ret = "0.0.0.0"; + break; + } + return ret; +} + diff --git a/src/Switch.h b/src/Switch.h index 1b40071..cb962ab 100644 --- a/src/Switch.h +++ b/src/Switch.h @@ -65,9 +65,13 @@ public: int parse(datasets); int parse(dataset); int parse(std::string); - int print(); + int set(std::pair); + + std::string get(std::string); std::string toString(); + int print(); + struct { std::string type; std::string hardware_version; diff --git a/src/Types.h b/src/Types.h index 489529a..e236c10 100644 --- a/src/Types.h +++ b/src/Types.h @@ -95,6 +95,14 @@ public: } }; +namespace smrtlink { + +constexpr unsigned int caseArg(const char* str, int h = 0) { + return !str[h] ? 5381 : (caseArg(str, h + 1) * 33) ^ str[h]; +} + +} + template std::vector operator+(const std::vector &A, const std::vector &B) { std::vector AB; @@ -117,6 +125,7 @@ struct Options { bool JSON; bool PLAIN; bool REVERSE; + bool HEADER; bool PERMANENT; bool WAIT; @@ -128,7 +137,7 @@ struct Options { std::string file; int debug_level = 0; int verbosity = 0; - long timeout = 180U; + long timeout = 250U; }; #endif /* TYPES_H_ */ diff --git a/src/lookup/input.lst b/src/lookup/input.lst index d673846..5c48cff 100644 --- a/src/lookup/input.lst +++ b/src/lookup/input.lst @@ -1,11 +1,13 @@ -LOOKUP_SET(TYPE,type, 1, STRING) //+string +LOOKUP_SET(type, TYPE, STRING) //+string +LOOKUP_SET(mac, MAC, HEX) //+byte[6] +LOOKUP_SET(firmware,FIRMWARE_VERSION, STRING) +LOOKUP_SET(hardware,HARDWARE_VERSION, STRING) + + LOOKUP_SET(HOSTNAME,host, 2, STRING) //+string -LOOKUP_SET(MAC,MAC, 3, HEX) //+byte[6] LOOKUP_SET(IP_ADDR,ip, 4, DEC) //+byte[4] LOOKUP_SET(IP_MASK,mask, 5, DEC) //+byte[4] LOOKUP_SET(GATEWAY,gateway, 6, DEC) //+byte[4] -LOOKUP_SET(FIRMWARE_VERSION,FIRMWARE_VERSION, 7, STRING) -LOOKUP_SET(HARDWARE_VERSION,HARDWARE_VERSION, 8, STRING) LOOKUP_SET(DHCP_ENABLED,dhcp, 9, BOOL) //+bool byte LOOKUP_SET(PORT_VLAN_FOOOOO, 2101,2101, HEX) diff --git a/src/smrtlink.cpp b/src/smrtlink.cpp index 73462ba..cf364ef 100644 --- a/src/smrtlink.cpp +++ b/src/smrtlink.cpp @@ -1,14 +1,13 @@ //============================================================================ // Name : smrtlink.cpp // Author : jdi -// Version : +// Version : 1.2 // Copyright : GPL v2 // Description : SmrtLink in C++, Ansi-style //============================================================================ #include #include -#include #include #include @@ -21,6 +20,7 @@ #include "Interactive.h" #include "Host.h" #include "Program.h" +#include "Types.h" #include "Switch.h" #include "lookup.h" @@ -32,12 +32,8 @@ using namespace std; Options options; -constexpr unsigned int caseArg(const char* str, int h = 0) { - return !str[h] ? 5381 : (caseArg(str, h + 1) * 33) ^ str[h]; -} - int main(int argc, char *argv[]) { - int index,opt; + int index, opt; options.user = DEFAULT_USER; options.password = DEFAULT_PASS; @@ -54,8 +50,6 @@ int main(int argc, char *argv[]) { 0, 't' }, { "wait", required_argument, 0, 'w' }, { 0, 0, 0, 0 }, }; - - while ((opt = getopt_long(argc, argv, "bhrvVXIswxP:U:i:f:t:d::", longopts, &index)) != -1) { switch (opt) { @@ -151,116 +145,20 @@ int main(int argc, char *argv[]) { if (options.flags.INTERACTIVE) { if (optind < argc) { - cerr << "Command is ignored in interactive mode\n"; - } + cerr << "Command is ignored in interactive mode\n"; + } Interactive p = Interactive(); - if (!p.run()) + if (!p.loop()) exit(EXIT_SUCCESS); fprintf(stderr, "Not yet implemented.\n"); exit(EXIT_FAILURE); - } - else if (optind < argc) { + } else if (optind < argc) { Program p = Program(); - p.init(); - std::vector vect; - std::map list; - std::cmatch sm; - std::string cmd = std::string(argv[optind++]); - switch (caseArg(cmd.c_str())) { - case caseArg("reboot"): - if (!p.reboot()) - exit(EXIT_SUCCESS); - fprintf(stderr, "Not yet implemented.\n"); - exit(EXIT_FAILURE); - break; - case caseArg("reset"): - if (!p.reset()) - exit(EXIT_SUCCESS); - fprintf(stderr, "Not yet implemented.\n"); - exit(EXIT_FAILURE); - break; - case caseArg("save"): - if (!p.save()) - exit(EXIT_SUCCESS); - fprintf(stderr, "Not yet implemented.\n"); - exit(EXIT_FAILURE); - break; - case caseArg("restore"): - if (!p.restore()) - exit(EXIT_SUCCESS); - fprintf(stderr, "Not yet implemented.\n"); - exit(EXIT_FAILURE); - break; - case caseArg("flash"): - if (!p.flash()) - exit(EXIT_SUCCESS); - fprintf(stderr, "Not yet implemented.\n"); - exit(EXIT_FAILURE); - break; - - case caseArg("list"): - if (!p.list()) - exit(EXIT_SUCCESS); - break; - - case caseArg("sniff"): - if (!p.sniff()) - exit(EXIT_SUCCESS); - break; - - case caseArg("encode"): - if (optind < argc) { - std::string s(argv[optind]); - optind++; - if (p.encode(s)) - exit(EXIT_SUCCESS); - } else { - fprintf(stderr, "Argument expected after encode\n"); - exit(EXIT_FAILURE); - } - break; - case caseArg("set"): - while (optind < argc) { - if (regex_match(argv[optind], sm, - std::regex("^([a-z]+)=(.*)$"))) { - if (!snd_lookup.exists(sm[1])&&!rcv_lookup.exists(sm[1])) { - cerr << "Unknown argument " << argv[optind] << endl; - exit(EXIT_FAILURE); - } - list.insert( - std::pair(sm[1], sm[2])); - } else { - cerr << "Invalid Syntax " << argv[optind] << endl; - exit(EXIT_FAILURE); - } - optind++; - } - if (!p.setProperty(list)) - exit(EXIT_SUCCESS); - fprintf(stderr, "Not yet implemented.\n"); - exit(EXIT_FAILURE); - break; - case caseArg("get"): - while (optind < argc) { - if (regex_match(argv[optind], sm, std::regex("^([a-z]+)$"))) { - if (!snd_lookup.exists(sm[1])&&!rcv_lookup.exists(sm[1])) { - cerr << "Unknown argument " << argv[optind] << endl; - exit(EXIT_FAILURE); - } - vect.push_back(sm[1]); - } else { - cerr << "Invalid argument " << argv[optind] << endl; - exit(EXIT_FAILURE); - } - optind++; - } - if (!p.getProperty(vect)) - exit(EXIT_SUCCESS); - break; - default: - printf("Unknown command: %s\n", cmd.c_str()); - exit(EXIT_FAILURE); - } + p.init(); + vector v; + while (optind < argc) + v.push_back(argv[optind++]); + p.run(v); } exit(EXIT_FAILURE); }