diff --git a/Makefile b/Makefile index 2404b58..1b4e939 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ $(BUILDDIR): $(TARGET): $(OBJECTS) - $(CC) $^ -o $(BUILDDIR)/$@ -lboost_filesystem -lboost_system + $(CC) $^ -o $(BUILDDIR)/$@ -lboost_filesystem -lboost_system -lboost_program_options -lpthread $(OBJECTS): $(BUILDDIR)/%.o : $(SOURCEDIR)/%.cpp diff --git a/src/Constant.h b/src/Constant.h index 31e73fc..c86c8f0 100644 --- a/src/Constant.h +++ b/src/Constant.h @@ -14,38 +14,40 @@ #define USAGE "usage: %s [-bdhjrvswx] [-i interface] [-u [password:]username]\n\ [-p password] \n\n" #define HELP "\ - Option Summary:\n\ - -h --help This help text\n\ - -v --version Display version of this tool\n\ - -d --debug [n] Show debugging messages\n\ - -r switch ports to emulate switch while sniffing\n\ - -b --header Show header\n\ - -x --hex Display Packets as Hex String\n\ - -j --json Display Packets as JSON\n\ - -i --interface only use one Interface\n\ - -u --user <[password:]username>\n\ - -p --password \n\ - Login with Username and Password\n\ - -f --file choose a settings file\n\n\ - -t --timeout Timeout in milliseconds. Default: 180\n\ - -I --interactive Not yet implemented\n\ - -O --stdout Not yet implemented\n\ - -w --wait Not yet implemented: blocking until operation is completed\n\ - -s --permanent Not yet implemented: make changes immediately permanent\n\n\ - Command Summary:\n\ - help This help text\n\ - list list all connected switches\n\ - sniff [type:] []\n\ - capture and display all incoming or outgoing packets\n\ - depending on the --reverse option\n\ - encode use encoding algorithm on hex data separated by colon\n\ - get Not yet implemented\n\ - set Not yet implemented\n\ - get|save Not yet implemented: save config to file\n\ - set|restore Not yet implemented: restore onfig from file\n\ - flash Not yet implemented: replace firmware\n\ - reboot Not yet implemented\n\ - reset Not yet implemented\n\n\ + Option Summary:\n\ + -h --help This help text\n\ + -V --version Display version of this tool\n\ + -d --debug [n] Show debugging messages\n\ + -v --verbose [n] Show debugging messages\n\ + -r --reverse switch ports to emulate switch while sniffing\n\ + -b --header Show header\n\ + -x --hex Display Packets as Hex String\n\ + -j --json Display Packets as JSON\n\ + -i --interface only use one Interface\n\ + -u --user <[password:]username>\n\ + -p --password \n\ + Login with Username and Password\n\ + -f --file choose a settings file\n\n\ + -t --timeout Timeout in milliseconds. Default: 180\n\ + -I --interactive Not yet implemented\n\ + -O --stdout Not yet implemented\n\ + -w --wait Not yet implemented: blocking until operation is completed\n\ + -s --permanent Not yet implemented: make changes immediately permanent\n\n\ + Command Summary:\n\ + list list all connected switches\n\ + sniff [type:] []\n\ + capture and display all incoming or outgoing packets\n\ + depending on the --reverse option\n\ + encode use encoding algorithm on hex data separated by colon\n\ + get [ [...]]\n\ + Not yet implemented\n\ + set = [= [...]]\n\ + Not yet implemented\n\ + get|save Not yet implemented: save config to file\n\ + set|restore Not yet implemented: restore onfig from file\n\ + flash Not yet implemented: replace firmware\n\ + reboot Not yet implemented\n\ + reset Not yet implemented\n\n\ ### for questions please contact ###\n\n" //TODO /* @@ -54,13 +56,6 @@ * */ -#define FLAG_HEX 1 -#define FLAG_REVERSE 2 -#define FLAG_HEADER 4 -#define FLAG_PERMANENT 8 -#define FLAG_WAIT 16 -#define FLAG_DEBUG 32 - extern Options options; #endif /* OPTIONS_H_ */ diff --git a/src/Options.h b/src/Options.h deleted file mode 100644 index 034ee3f..0000000 --- a/src/Options.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Options.h - * - * Created on: 11.09.2015 - * Author: jdi - */ - -#ifndef OPTIONS_H_ -#define OPTIONS_H_ - -#include "Types.h" - -#define VERSION "smrtlink (v1 Linux)\n" -#define USAGE "usage: %s [-bdhjrvswx] [-i interface] [-u [password:]username]\n\ - [-p password] \n\n" -#define HELP "\ - Option Summary:\n\ - -h --help This help text\n\ - -v --version Display version of this tool\n\ - -d --debug [n] Show debugging messages\n\ - -r switch ports to emulate switch while sniffing\n\ - -b --header Show header\n\ - -x --hex Display Packets as Hex String\n\ - -j --json Display Packets as JSON\n\ - -i --interface only use one Interface\n\ - -u --user <[password:]username>\n\ - -p --password \n\ - Login with Username and Password\n\ - -f --file choose a settings file\n\n\ - -t --timeout Timeout in milliseconds. Default: 180\n\ - -I --interactive Not yet implemented\n\ - -O --stdout Not yet implemented\n\ - -w --wait Not yet implemented: blocking until operation is completed\n\ - -s --permanent Not yet implemented: make changes immediately permanent\n\n\ - Command Summary:\n\ - help This help text\n\ - list list all connected switches\n\ - sniff [type:] []\n\ - capture and display all incoming or outgoing packets\n\ - depending on the --reverse option\n\ - encode use encoding algorithm on hex data separated by colon\n\ - get Not yet implemented\n\ - set Not yet implemented\n\ - get|save Not yet implemented: save config to file\n\ - set|restore Not yet implemented: restore onfig from file\n\ - flash Not yet implemented: replace firmware\n\ - reboot Not yet implemented\n\ - reset Not yet implemented\n\n\ - ### for questions please contact ###\n\n" -//TODO -/* - * Stdin - * socketmode - * - */ - -#define FLAG_HEX 1 -#define FLAG_REVERSE 2 -#define FLAG_HEADER 4 -#define FLAG_PERMANENT 8 -#define FLAG_WAIT 16 -#define FLAG_DEBUG 32 - -extern Options options; - -#endif /* OPTIONS_H_ */ diff --git a/src/Packet.cpp b/src/Packet.cpp index ce3ad13..0e61bf7 100644 --- a/src/Packet.cpp +++ b/src/Packet.cpp @@ -277,6 +277,14 @@ void Packet::pull(bytes &arr, int &index, int &ret) { ret |= arr[index++] & 0xFF; } +byte Packet::getOpCode() const { + return opCode; +} + +void Packet::setOpCode(byte opCode) { + this->opCode = opCode; +} + void Packet::pull(bytes &arr, int &index, dataset &ret) { pull(arr, index, ret.type); pull(arr, index, ret.len); diff --git a/src/Packet.h b/src/Packet.h index 327e713..2e04a2d 100644 --- a/src/Packet.h +++ b/src/Packet.h @@ -20,7 +20,7 @@ class Packet public: enum OpCode {DISCOVERY, GET, RETURN, SET, CONFIRM, NONE}; Packet(OpCode); - void encode(bytes&); + static void encode(bytes&); bytes getBytes(); void parse(bytes); void printHeader(); @@ -41,6 +41,8 @@ public: void setPayload(datasets payload); short getTokenId() const; void setTokenId(short tokenId = 0); + byte getOpCode() const; + void setOpCode(byte opCode); private: bytes head = bytes(32); diff --git a/src/Program.cpp b/src/Program.cpp index 636ed70..a2c3ee5 100644 --- a/src/Program.cpp +++ b/src/Program.cpp @@ -18,8 +18,8 @@ #include "table.h" int printHeader(Packet p) { - if (options.flags & FLAG_HEADER) { - if (options.flags & FLAG_HEX) { + if (options.flags.HEADER) { + if (options.flags.HEX) { std::cout << "Received Header:\n\t" << p.getHead() << "\n"; } else { p.printHeader(); @@ -30,12 +30,12 @@ int printHeader(Packet p) { } int printPacket(Packet p) { - if (options.flags & FLAG_HEX) { + if (options.flags.HEX) { std::cout << "Received Payload:\n\t" << p.getBody() << "\n"; } else { for (dataset d : p.getPayload()) { auto lookup = - (options.flags & FLAG_REVERSE) ? snd_lookup : rcv_lookup; + (options.flags.REVERSE) ? snd_lookup : rcv_lookup; if (lookup.exists(d.type)) { table::set s = lookup[d.type]; if (d.len > 0) { @@ -88,38 +88,27 @@ int printPacket(Packet p) { } int Program::list() { - - std::cout << "List:\n"; - Packet p = Packet(Packet::DISCOVERY); - p.setHostMac(host.getMac()); - p.setPayload( { }); - bytes b = p.getBytes(); - p.encode(b); - try { - sock->setHostIp(host.getIp()); - sock->init(DST_PORT, SRC_PORT); - sock->callback = - [this](Packet a) { - printHeader(a); - if (options.flags & FLAG_HEX) { - std::cout <<"Received Payload:\n"<send(b); + std::cout << "List:\n"; + discover([this](Packet a) { + printHeader(a); + if (options.flags.HEX) { + std::cout <<"Received Payload:\n"<run(); } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; } - return 1; + return 0; } int Program::sniff() { @@ -141,91 +130,80 @@ int Program::sniff() { std::cerr << "Exception: " << e.what() << "\n"; } - return 1; + return 0; } int Program::encode(std::string s) { bytes d(s); - Packet p = Packet(Packet::DISCOVERY); + Packet p = Packet(Packet::NONE); p.encode(d); std::cout << d << std::endl; return 0; } -int Program::setProperty() { - return 0; -} - -int Program::getProperty() { - std::cout << "List:\n"; - Packet p = Packet(Packet::DISCOVERY); - p.setHostMac(host.getMac()); - p.setPayload( { }); - bytes b = p.getBytes(); - p.encode(b); - auto s = sock; +int Program::setProperty(std::map prop) { try { - sock->setHostIp(host.getIp()); - sock->init(DST_PORT, SRC_PORT); - sock->callback = + + std::cout << "List:\n"; + discover( [this](Packet a) { - auto s = sock; datasets d =a.getPayload(); Switch sw = Switch(); sw.parse(d); - std::cout <<"\t"<callback = - [this](Packet a) { - auto s = sock; - datasets d =a.getPayload(); - Switch sw = Switch(); - sw.parse(d); - Packet p = Packet(Packet::SET); - p.setSwitchMac(a.getSwitchMac()); - p.setTokenId(a.getTokenId()); - p.setHostMac(host.getMac()); - bytes n = options.user; - bytes w = options.password; - n.push_back('\0'); - w.push_back('\0'); - datasets t = { - { LOGIN_USER, (short)(n.size()), n}, - { LOGIN_PASSWORD, (short)(w.size()), w}, - { REBOOT, 1, {0}} - }; - p.setPayload(t); - bytes c = p.getBytes(); - p.encode(c); + datasets t = { {LOOP_PREVENTION, 1, {0}}}; + set(a,t, - sock->callback = - [this](Packet a) { - std::cout << a.opCodeToString() << "\n"; - printHeader(a); - printPacket(a); - return 0; - }; - sock->send(c); - return 0; - }; - - sock->send(c); + [this](Packet a) { + std::cout << a.opCodeToString() << "\n"; + printHeader(a); + printPacket(a); + return 0; + }); + return 0; + }); return 0; - }; - sock->send(b); + }); + io_service->run(); } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; } - return 1; + return 0; +} + +int Program::getProperty(std::vector prop) { + try { + std::cout << "List:\n"; + discover([this](Packet a) { + + datasets d =a.getPayload(); + Switch sw = Switch(); + sw.parse(d); + sw.print(); + + datasets t = { {SYSTEM_INFO, 0, {}}}; + get(a, t, [this](Packet a) { + std::cout << a.opCodeToString() << "\n"; + printHeader(a); + printPacket(a); + return 0; + }); + return 0; + }); + + io_service->run(); + } catch (std::exception& e) { + std::cerr << "Exception: " << e.what() << "\n"; + } + return 0; } int Program::save() { @@ -233,40 +211,96 @@ int Program::save() { sw.settings.hostname = "testname.lan"; File f; f.write(sw.toString()); - return 1; + return 0; } int Program::restore() { File f; Switch sw; sw.parse(f.read()); - std::cout << "Devices:\n\t" << sw.settings.hostname << " (" - << sw.device.type << ")\tMAC: " << sw.device.mac << "\tIP: " - << sw.settings.ip_addr << "\n"; - return 1; + sw.print(); + return 0; } int Program::flash() { - return 0; + return 1; } int Program::reboot() { - + try { + discover([this](Packet a) { + datasets d =a.getPayload(); + Switch sw = Switch(); + sw.parse(d); + std::cout <run(); + } catch (std::exception& e) { + std::cerr << "Exception: " << e.what() << "\n"; + } return 0; } int Program::reset() { + return 1; +} + +int Program::discover(std::function c) { + Packet p = Packet(Packet::DISCOVERY); + p.setHostMac(host.getMac()); + p.setPayload( { }); + sock->callback = c; + sock->send(p); return 0; } -int Program::ping(std::function) { +int Program::get(Packet l, datasets t, std::function c) { + Packet p = Packet(Packet::GET); + p.setSwitchMac(l.getSwitchMac()); + p.setHostMac(host.getMac()); + p.setPayload(t); + sock->callback = c; + sock->send(p); + return 0; +} +int Program::set(Packet l, datasets t, std::function c) { + Packet p = Packet(Packet::SET); + p.setSwitchMac(l.getSwitchMac()); + p.setTokenId(l.getTokenId()); + p.setHostMac(host.getMac()); + bytes n = options.user; + bytes w = options.password; + n.push_back('\0'); + w.push_back('\0'); + datasets ld = { { LOGIN_USER, (short) (n.size()), n }, { LOGIN_PASSWORD, + (short) (w.size()), w } }; + p.setPayload(ld + t); + sock->callback = c; + sock->send(p); return 0; } void Program::init() { if (options.interface.compare("") == 0) options.interface = host.getIface(); + + sock->setHostIp(host.getIp()); + sock->init(DST_PORT, SRC_PORT); } diff --git a/src/Program.h b/src/Program.h index 1bd97da..02dbedd 100644 --- a/src/Program.h +++ b/src/Program.h @@ -14,12 +14,15 @@ #include "Host.h" #include "Socket.h" + class Program { private: std::shared_ptr io_service; std::shared_ptr sock; Host host = Host(); - int ping(std::function); + int get(Packet,datasets,std::function); + int set(Packet,datasets,std::function); + int discover(std::function); public: Program() { io_service = std::make_shared(); @@ -29,8 +32,8 @@ public: int list(); int sniff(); int encode(std::string); - int setProperty(); - int getProperty(); + int getProperty(std::vector); + int setProperty(std::map); int save(); int restore(); int flash(); diff --git a/src/Socket.cpp b/src/Socket.cpp index 191971e..2d0e363 100644 --- a/src/Socket.cpp +++ b/src/Socket.cpp @@ -21,13 +21,13 @@ void Socket::init(short dst_port, short src_port) { if (initialized) return; - if (options.flags & FLAG_REVERSE) { + if (options.flags.REVERSE) { short p = dst_port; dst_port = src_port; src_port = p; } - if (options.flags & FLAG_DEBUG) + if (options.debug_level>=1) std::cout << "Local IP:\t" << local_ip << "\n"; wildcard_endpoint_ = boost::asio::ip::udp::endpoint( @@ -67,7 +67,9 @@ void Socket::setHostIp(ipAddr ip) { local_ip = ip; } -void Socket::send(bytes data) { +void Socket::send(Packet p) { + bytes data = p.getBytes(); + p.encode(data); unsigned char * a = &data[0]; send_socket_.async_send_to(boost::asio::buffer(a, data.size()), broadcast_endpoint_, diff --git a/src/Socket.h b/src/Socket.h index 6bda28a..7abce0d 100644 --- a/src/Socket.h +++ b/src/Socket.h @@ -23,7 +23,7 @@ public: virtual ~Socket() { } void init(short, short); - void send(bytes); + void send(Packet); void listen(); void setHostIp(ipAddr); std::function callback = [](Packet a) { diff --git a/src/Switch-Json.cpp b/src/Switch-Json.cpp index 21f1477..c94961c 100644 --- a/src/Switch-Json.cpp +++ b/src/Switch-Json.cpp @@ -16,7 +16,7 @@ int Switch::parse(std::string str) { if (json.Parse(str.c_str()).HasParseError()) return 1; - if (options.flags & FLAG_DEBUG) + if (options.debug_level>=1) std::cout << "\nParsing to document succeeded.\n"; if (json.IsObject()) { diff --git a/src/Switch.cpp b/src/Switch.cpp index 89419a8..0d6966e 100644 --- a/src/Switch.cpp +++ b/src/Switch.cpp @@ -19,6 +19,12 @@ int Switch::parse(datasets arr) { return 0; } +int Switch::print() { + std::cout << "\t" << settings.hostname << " (" << device.type << ")\tMAC: " + << device.mac << "\tIP: " << settings.ip_addr << "\n"; + return 0; +} + int Switch::parse(dataset d) { switch (d.type) { case RCV_TYPE: @@ -63,4 +69,3 @@ int Switch::parse(dataset d) { } return 0; } - diff --git a/src/Switch.h b/src/Switch.h index 88a3351..1b40071 100644 --- a/src/Switch.h +++ b/src/Switch.h @@ -65,6 +65,7 @@ public: int parse(datasets); int parse(dataset); int parse(std::string); + int print(); std::string toString(); struct { diff --git a/src/Types.h b/src/Types.h index 019c07f..3797d1d 100644 --- a/src/Types.h +++ b/src/Types.h @@ -21,105 +21,113 @@ class macAddr: public std::array { public: - friend std::ostream& operator<<(std::ostream& out, const macAddr& arr) { - out << std::hex << std::setw(2) << std::setfill('0') - << (unsigned) arr[0]; - for (unsigned i = 1; i < 6; i++) { - out << ":" << std::setw(2) << std::setfill('0') - << (unsigned) arr[i]; - } - return out; - } + friend std::ostream& operator<<(std::ostream& out, const macAddr& arr) { + out << std::hex << std::setw(2) << std::setfill('0') + << (unsigned) arr[0]; + for (unsigned i = 1; i < 6; i++) { + out << ":" << std::setw(2) << std::setfill('0') + << (unsigned) arr[i]; + } + return out; + } - macAddr() { - *this= {0,0,0,0,0,0}; - } + macAddr() { + *this= {0,0,0,0,0,0}; + } - macAddr(std::initializer_list s) { - int i = 0; + macAddr(std::initializer_list s) { + int i = 0; for (byte b : s) { - if(i<6) (*this)[i++]=b; - else break; + if(i<6) (*this)[i++]=b; + else break; } - } + } - macAddr(bytes bts) { - int i = 0; + macAddr(bytes bts) { + int i = 0; for (byte b : bts) { - if(i<6) (*this)[i++]=b; - else break; + if(i<6) (*this)[i++]=b; + else break; } - } + } }; /* -class mac_addr : public std::array { -public: - typedef std::array super; + class mac_addr : public std::array { + public: + typedef std::array super; - using super::super; - - mac_addr{00, 00, 00, 000}; -}; -*/ + using super::super; + mac_addr{00, 00, 00, 000}; + }; + */ class ipAddr: public std::array { public: - ipAddr() { - *this= {0,0,0,0,0,0}; - } + ipAddr() { + *this= {0,0,0,0,0,0}; + } - ipAddr(std::initializer_list s) { - int i = 0; - for (byte b : s) { - if(i<4) (*this)[i++]=b; - else break; + ipAddr(std::initializer_list s) { + int i = 0; + for (byte b : s) { + if(i<4) (*this)[i++]=b; + else break; } - } + } - ipAddr(bytes bts) { - int i = 0; + ipAddr(bytes bts) { + int i = 0; for (byte b : bts) { - if(i<4) (*this)[i++]=b; - else break; + if(i<4) (*this)[i++]=b; + else break; } - } + } - friend std::ostream& operator<<(std::ostream& out, ipAddr& arr) { - out << std::dec << (unsigned) arr[0]; - for (unsigned i = 1; i < 4; i++) { - out << "." << (unsigned) arr[i]; - } - return out; - } + friend std::ostream& operator<<(std::ostream& out, ipAddr& arr) { + out << std::dec << (unsigned) arr[0]; + for (unsigned i = 1; i < 4; i++) { + out << "." << (unsigned) arr[i]; + } + return out; + } }; template std::vector operator+(const std::vector &A, const std::vector &B) { - std::vector AB; - AB.reserve(A.size() + B.size()); // preallocate memory - AB.insert(AB.end(), A.begin(), A.end()); // add A; - AB.insert(AB.end(), B.begin(), B.end()); // add B; - return AB; + std::vector AB; + AB.reserve(A.size() + B.size()); // preallocate memory + AB.insert(AB.end(), A.begin(), A.end()); // add A; + AB.insert(AB.end(), B.begin(), B.end()); // add B; + return AB; } template std::vector &operator+=(std::vector &A, const std::vector &B) { - A.reserve(A.size() + B.size()); - A.insert(A.end(), B.begin(), B.end()); - return A; + A.reserve(A.size() + B.size()); + A.insert(A.end(), B.begin(), B.end()); + return A; } struct Options { - unsigned flags = 0x00; - std::string user; - std::string password; - std::string interface; - std::string file; - int debug_level=0; - long timeout = 180U; + struct { + bool HEX; + bool JSON; + bool PLAIN; + bool REVERSE; + bool HEADER; + bool PERMANENT; + bool WAIT; + } flags; + std::string user; + std::string password; + std::string interface; + std::string file; + int debug_level = 0; + int verbosity = 0; + long timeout = 180U; }; #endif /* TYPES_H_ */ diff --git a/src/datasets.h b/src/datasets.h index bc9ac83..7b08f4f 100644 --- a/src/datasets.h +++ b/src/datasets.h @@ -27,6 +27,14 @@ public: push_back(b); } } + + datasets operator+(const datasets &B) { + datasets AB; + AB.reserve(this->size() + B.size()); + AB.insert(AB.end(), this->begin(), this->end()); + AB.insert(AB.end(), B.begin(), B.end()); + return AB; + } }; #endif /* DATASETS_H_ */ diff --git a/src/future.cpp b/src/future.cpp new file mode 100644 index 0000000..409d53b --- /dev/null +++ b/src/future.cpp @@ -0,0 +1,79 @@ +#include +#include +#include +#include +#include + +void asyncRun() { + std::cout << "Async..." << std::flush; + + boost::asio::io_service io_service; + std::shared_ptr < std::promise > promise(new std::promise()); + std::future future = promise->get_future(); + + io_service.post([promise]() + { + std::chrono::milliseconds dura( 2000 ); + std::this_thread::sleep_for( dura ); + promise->set_value(9); + }); + + std::thread t1([&io_service] {io_service.run();}); + t1.detach(); + + std::cout << "Waiting..." << std::flush; + future.wait(); + std::cout << "Done!\nResults are: " << future.get() << '\n'; + +} + +void nonBlockingRun() { + std::cout << "Non Blocking..." << std::flush; + + std::promise promise; + std::future future = promise.get_future(); + std::thread t1([](std::promise p) + { + std::chrono::milliseconds dura( 2000 ); + std::this_thread::sleep_for( dura ); + p.set_value(9); + }, std::move(promise)); + t1.detach(); + + std::cout << "Waiting...\n" << std::flush; + std::future_status status; + do { + status = future.wait_for(std::chrono::seconds(0)); + + if (status == std::future_status::deferred) { + std::cout << "+"; + } else if (status == std::future_status::timeout) { + std::cout << "."; + } + } while (status != std::future_status::ready); + std::cout << "Done!\nResults are: " << future.get() << '\n'; +} + +void blockingRun() { + std::cout << "Blocking..." << std::flush; + + std::promise promise; + std::future future = promise.get_future(); + std::thread t1([](std::promise p) + { + std::chrono::milliseconds dura( 2000 ); + std::this_thread::sleep_for( dura ); + p.set_value(9); + }, std::move(promise)); + t1.detach(); + + std::cout << "Waiting..." << std::flush; + future.wait(); + std::cout << "Done!\nResults are: " << future.get() << '\n'; +} + +int main2() { + nonBlockingRun(); + blockingRun(); + asyncRun(); +} diff --git a/src/lookup.h b/src/lookup.h index a51f9bf..faed805 100644 --- a/src/lookup.h +++ b/src/lookup.h @@ -1,13 +1,13 @@ enum { -#define LOOKUP_SET(id, num, type) RCV_ ## id = num, +#define LOOKUP_SET(id, name, num, type) RCV_ ## id = num, #include "lookup/rcv.lst" #include "lookup/general.lst" #undef LOOKUP_SET -#define LOOKUP_SET(id, num, type) SND_ ## id = num, +#define LOOKUP_SET(id, name, num, type) SND_ ## id = num, #include "lookup/snd.lst" #include "lookup/general.lst" #undef LOOKUP_SET -#define LOOKUP_SET(id, num, type) id = num, +#define LOOKUP_SET(id, name, num, type) id = num, #include "lookup/rcv.lst" #include "lookup/snd.lst" #include "lookup/general.lst" @@ -15,14 +15,14 @@ enum { }; static table rcv_lookup { -#define LOOKUP_SET(id, num, type) { RCV_ ## id, table::type, #id }, +#define LOOKUP_SET(id, name, num, type) { RCV_ ## id, table::type, #name, #id }, #include "lookup/rcv.lst" #include "lookup/general.lst" #undef LOOKUP_SET }; static table snd_lookup { -#define LOOKUP_SET(id, num, type) { SND_ ## id, table::type, #id }, +#define LOOKUP_SET(id, name, num, type) { SND_ ## id, table::type, #name, #id }, #include "lookup/snd.lst" #include "lookup/general.lst" #undef LOOKUP_SET diff --git a/src/lookup/general.lst b/src/lookup/general.lst index c4a4f05..3dba23d 100644 --- a/src/lookup/general.lst +++ b/src/lookup/general.lst @@ -1,25 +1,25 @@ -LOOKUP_SET(PORTS, 10, DEC) //+byte, maybe number of ports +LOOKUP_SET(PORTS, ports, 10, DEC) //+byte, maybe number of ports -LOOKUP_SET(IGMP_SNOOPING, 4352, HEX) //??? -LOOKUP_SET(PORTS_SETTINGS, 4096, HEX) //+per port -LOOKUP_SET(PORT_TRUNK, 4608, HEX) //byte[5] last byte bitmask?? +LOOKUP_SET(IGMP_SNOOPING, igmp, 4352, HEX) //??? +LOOKUP_SET(PORTS_SETTINGS, psetings, 4096, HEX) //+per port +LOOKUP_SET(PORT_TRUNK, trunk, 4608, HEX) //byte[5] last byte bitmask?? -LOOKUP_SET(MTU_VLAN, 8192, HEX) //byte[2] first byte bool,second byte port id -LOOKUP_SET(PORT_VLAN_ENABLED, 8448, BOOL) //open page -LOOKUP_SET(PORT_VLAN, 8449, HEX) -LOOKUP_SET(PORT_VLAN_MAX, 8450, DEC) -LOOKUP_SET(VLAN_ENABLED, 8704, BOOL) //+bool byte -LOOKUP_SET(VLAN, 8705, HEX) //+one set per vlan -LOOKUP_SET(VLAN_PVID, 8706, HEX) //+per port -LOOKUP_SET(VLAN_FOOOO, 8707, DEC) //???? +LOOKUP_SET(MTU_VLAN, 8192,8192, HEX) //byte[2] first byte bool,second byte port id +LOOKUP_SET(PORT_VLAN_ENABLED, 8448,8448, BOOL) //open page +LOOKUP_SET(PORT_VLAN, 8449,8449, HEX) +LOOKUP_SET(PORT_VLAN_MAX, 8450,8450, DEC) +LOOKUP_SET(VLAN_ENABLED, 8704, 8704, BOOL) //+bool byte +LOOKUP_SET(VLAN, 8705,8705, HEX) //+one set per vlan +LOOKUP_SET(VLAN_PVID, 8706,8706, HEX) //+per port +LOOKUP_SET(VLAN_FOOOO, 8707,8707, DEC) //???? -LOOKUP_SET(QOS_BASIC_ENABLED, 12288, BOOL) //+bool = QoS Mod -LOOKUP_SET(QOS_BASIC, 12289, HEX) //+per port ??? -LOOKUP_SET(BW_CONTROL_INGRESS, 12544, HEX) //+per port ??? -LOOKUP_SET(BW_CONTROL_EGRESS, 12545, HEX) //+per port ??? -LOOKUP_SET(STORM_CONTROL, 12800, HEX) //+per port ??? -LOOKUP_SET(PORT_MIRROR, 16640, HEX) //byte[10] second byte port id??? -LOOKUP_SET(PORT_STATISTICS, 16384, HEX) //+per port ??? -LOOKUP_SET(CABLE_TEST, 16896, HEX) //+per port ??? -LOOKUP_SET(LOOP_PREVENTION, 17152, BOOL) //+bool byte +LOOKUP_SET(QOS_BASIC_ENABLED, 12288,12288, BOOL) //+bool = QoS Mod +LOOKUP_SET(QOS_BASIC, 12289,12289, HEX) //+per port ??? +LOOKUP_SET(BW_CONTROL_INGRESS, 12544,12544, HEX) //+per port ??? +LOOKUP_SET(BW_CONTROL_EGRESS, 12545,12545, HEX) //+per port ??? +LOOKUP_SET(STORM_CONTROL, 12800,12800, HEX) //+per port ??? +LOOKUP_SET(PORT_MIRROR, 16640,16640, HEX) //byte[10] second byte port id??? +LOOKUP_SET(PORT_STATISTICS, 16384,16384, HEX) //+per port ??? +LOOKUP_SET(CABLE_TEST, 16896,16896, HEX) //+per port ??? +LOOKUP_SET(LOOP_PREVENTION, 17152,17152, BOOL) //+bool byte diff --git a/src/lookup/rcv.lst b/src/lookup/rcv.lst index 7380ef2..f7cee17 100644 --- a/src/lookup/rcv.lst +++ b/src/lookup/rcv.lst @@ -1,13 +1,13 @@ -LOOKUP_SET(TYPE, 1, STRING) //+string -LOOKUP_SET(HOSTNAME, 2, STRING) //+string -LOOKUP_SET(MAC, 3, HEX) //+byte[6] -LOOKUP_SET(IP_ADDR, 4, DEC) //+byte[4] -LOOKUP_SET(IP_MASK, 5, DEC) //+byte[4] -LOOKUP_SET(GATEWAY, 6, DEC) //+byte[4] -LOOKUP_SET(FIRMWARE_VERSION, 7, STRING) -LOOKUP_SET(HARDWARE_VERSION, 8, STRING) -LOOKUP_SET(DHCP_ENABLED, 9, BOOL) //+bool byte +LOOKUP_SET(TYPE,type, 1, STRING) //+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, HEX) +LOOKUP_SET(PORT_VLAN_FOOOOO, 2101,2101, HEX) diff --git a/src/lookup/snd.lst b/src/lookup/snd.lst index d254a39..797512e 100644 --- a/src/lookup/snd.lst +++ b/src/lookup/snd.lst @@ -1,17 +1,17 @@ -LOOKUP_SET(SYSTEM_INFO, 2, HEX) //page sysinfo -LOOKUP_SET(IP_CONFIG, 9, HEX) //page sysinfo +LOOKUP_SET(SYSTEM_INFO,SYSTEM_INFO, 2, HEX) //page sysinfo +LOOKUP_SET(IP_CONFIG,IP_CONFIG, 9, HEX) //page sysinfo -LOOKUP_SET(LOGIN_USER, 512, STRING) //string -LOOKUP_SET(NEW_USER, 513, STRING) //string -LOOKUP_SET(LOGIN_PASSWORD, 514, STRING) //string -LOOKUP_SET(NEW_PASSWORD, 515, STRING) //string -LOOKUP_SET(REBOOT, 773, BOOL) //bool byte = save config +LOOKUP_SET(LOGIN_USER,LOGIN_USER, 512, STRING) //string +LOOKUP_SET(NEW_USER,NEW_USER, 513, STRING) //string +LOOKUP_SET(LOGIN_PASSWORD,LOGIN_PASSWORD, 514, STRING) //string +LOOKUP_SET(NEW_PASSWORD,NEW_PASSWORD, 515, STRING) //string +LOOKUP_SET(REBOOT,REBOOT, 773, BOOL) //bool byte = save config -LOOKUP_SET(RESET, 1280, ACTION) // -LOOKUP_SET(FLASH, 1536, ACTION) //update firmware -LOOKUP_SET(VLAN_FOOOOOO, 2200, HEX) //vlan -LOOKUP_SET(SAVE, 2304, ACTION) //save -LOOKUP_SET(PING, 2305, ACTION) //sent before SET ??? +LOOKUP_SET(RESET,RESET, 1280, ACTION) // +LOOKUP_SET(FLASH,FLASH, 1536, ACTION) //update firmware +LOOKUP_SET(VLAN_FOOOOOO, 2200,2200, HEX) //vlan +LOOKUP_SET(SAVE,SAVE, 2304, ACTION) //save +LOOKUP_SET(PING,PING, 2305, ACTION) //sent before SET ??? diff --git a/src/smrtlink.cpp b/src/smrtlink.cpp index 8a821ee..de126e3 100644 --- a/src/smrtlink.cpp +++ b/src/smrtlink.cpp @@ -1,7 +1,7 @@ //============================================================================ // Name : smrtlink.cpp // Author : jdi -// Version : +// Version : 1.1 // Copyright : GPL v2 // Description : SmrtLink in C++, Ansi-style //============================================================================ @@ -13,7 +13,7 @@ #include #include -#include +#include #include #include "Constant.h" @@ -25,197 +25,164 @@ #define required_argument 1 #define optional_argument 2 +using namespace std; +namespace po = boost::program_options; + Options options; constexpr unsigned int caseArg(const char* str, int h = 0) { - return !str[h] ? 5381 : (caseArg(str, h + 1) * 33) ^ str[h]; + return !str[h] ? 5381 : (caseArg(str, h + 1) * 33) ^ str[h]; } -int main(int argc, char *argv[]) { - int opt, index; +int main3(int argc, char *argv[]) { + int opt, index; - options.user = DEFAULT_USER; - options.password = DEFAULT_PASS; + options.user = DEFAULT_USER; + options.password = DEFAULT_PASS; - const struct option longopts[] = { { "version", no_argument, 0, 'v' }, { - "help", no_argument, 0, 'h' }, { "reverse", no_argument, 0, 'r' }, { - "permanent", no_argument, 0, 's' }, { "debug", optional_argument, 0, - 'd' }, { "password", required_argument, 0, 'p' }, { "user", - required_argument, 0, 'u' }, { "interface", required_argument, 0, 'i' }, { - "header", required_argument, 0, 'b' }, { "hex", required_argument, - 0, 'x' }, { "file", required_argument, 0, 'f' }, { "timeout", - required_argument, 0, 't' }, { "wait", - required_argument, 0, 'w' }, { 0, 0, 0, 0 }, }; + // Declare the supported options. + po::options_description desc("Option Summary"); + desc.add_options()("help,h", "Display this help text")("version,V", + "Display version of this tool")("reverse,r", + po::bool_switch(&options.flags.REVERSE)->default_value(false), + "switch ports to emulate switch while sniffing")("permanent,s", + po::bool_switch(&options.flags.PERMANENT)->default_value(false), + "Not yet implemented: make changes immediately permanent")("hex,x", + po::bool_switch(&options.flags.HEX)->default_value(false), + "Display Packets as Hex String")("json,j", + po::bool_switch(&options.flags.JSON)->default_value(false), + "Display Packets as JSON")("header,b", + po::bool_switch(&options.flags.HEADER)->default_value(false), + "Show header")("wait,w", + po::bool_switch(&options.flags.WAIT)->default_value(false), + "Not yet implemented: blocking until operation is completed")( + "debug,d", + po::value()->implicit_value(1)->default_value(0)->value_name( + "n"), "Show debugging messages")("password,p", + po::value(&options.password)->value_name("password"), "")( + "user,u", po::value()->value_name("username"), "")( + "interface,i", + po::value(&options.interface)->value_name("iface"), + "only use one Interface")("file,f", + po::value(&options.file)->value_name("path"), + "choose a settings file")("timeout,t", + po::value(&options.timeout)->default_value(180L)->value_name( + "n"), "Timeout in milliseconds")("verbose,v", + po::value()->implicit_value(1)->default_value(0)->value_name( + "n"), "verbosity level"); - Program p = Program(); + po::variables_map vm; + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); - while ((opt = getopt_long(argc, argv, "bhrvswxp:u:i:f:t:d::", longopts, - &index)) != -1) { - switch (opt) { + if (vm.count("help")) { + cerr << VERSION; + cerr << USAGE; + cerr << desc << "\n"; + cerr << HELP; + exit(EXIT_SUCCESS); + return 1; + } - case 'h': - fprintf(stderr, VERSION); - fprintf(stderr, USAGE, argv[0]); - fprintf(stderr, HELP); - exit(EXIT_SUCCESS); - break; + if (vm.count("version")) { + cerr << VERSION; + exit(EXIT_SUCCESS); + return 1; + } - case 'v': - fprintf(stderr, VERSION); - exit(EXIT_SUCCESS); - break; + Program p = Program(); - case 'r': - options.flags |= FLAG_REVERSE; - break; + /*//TODO stdin + std::ostringstream bucket; + bucket << std::cin.rdbuf(); + p.input = bucket.str(); + */ - case 'b': - options.flags |= FLAG_HEADER; - break; + if (optind >= argc) { + fprintf(stderr, "Command expected\n"); + fprintf(stderr, USAGE, argv[0]); + exit(EXIT_FAILURE); + } - case 'x': - options.flags |= FLAG_HEX; - break; + p.init(); - case 's': - options.flags |= FLAG_PERMANENT; - break; + if (optind < argc) { + std::string cmd = std::string(argv[optind++]); - case 'w': - options.flags |= FLAG_WAIT; - break; + switch (caseArg(cmd.c_str())) { + case caseArg("set"): + while (optind < argc) { + printf("+%s\n", argv[optind]); + optind++; + } + if (!p.setProperty({})) + exit(EXIT_SUCCESS); + fprintf(stderr, "Not yet implemented.\n"); + exit(EXIT_FAILURE); + break; + 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 'd': - options.flags |= FLAG_DEBUG; - if (optarg != NULL) - options.debug_level = atoi(optarg); - break; + case caseArg("get"): + if (!p.getProperty({})) + exit(EXIT_SUCCESS); + break; - case 't': - options.timeout = atol(optarg); - break; + case caseArg("list"): + if (!p.list()) + exit(EXIT_SUCCESS); + break; - case 'f': - options.file = std::string(optarg); - break; + case caseArg("sniff"): + if (!p.sniff()) + exit(EXIT_SUCCESS); + break; - case 'p': - options.password = std::string(optarg); - 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 'u': - options.user = std::string(optarg); - break; - - case 'i': - options.interface = std::string(optarg); - break; - - default: /* '?' */ - fprintf(stderr, "Unknown option\n"); - fprintf(stderr, USAGE, argv[0]); - exit(EXIT_FAILURE); - } - } - - /*//TODO stdin - std::ostringstream bucket; - bucket << std::cin.rdbuf(); - p.input = bucket.str(); - */ - - if (optind >= argc) { - fprintf(stderr, "Command expected\n"); - fprintf(stderr, USAGE, argv[0]); - exit(EXIT_FAILURE); - } - - p.init(); - - if (optind < argc) { - std::string cmd = std::string(argv[optind++]); - - switch (caseArg(cmd.c_str())) { - case caseArg("set"): - if (p.setProperty()) - exit(EXIT_SUCCESS); - fprintf(stderr, "Not yet implemented.\n"); - exit(EXIT_FAILURE); - break; - 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("get"): - if (p.getProperty()) - exit(EXIT_SUCCESS); - 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("help"): - fprintf(stderr, VERSION); - fprintf(stderr, USAGE, argv[0]); - fprintf(stderr, HELP); - exit(EXIT_SUCCESS); - break; - - default: - printf("Unknown command: %s\n", cmd.c_str()); - while (optind < argc) { - printf("->%s\n", argv[optind]); - optind++; - } - exit(EXIT_FAILURE); - } - } - exit(EXIT_FAILURE); + default: + printf("Unknown command: %s\n", cmd.c_str()); + exit(EXIT_FAILURE); + } + } + exit(EXIT_FAILURE); } diff --git a/src/table.cpp b/src/table.cpp index e207490..f159ced 100644 --- a/src/table.cpp +++ b/src/table.cpp @@ -8,18 +8,35 @@ #include #include "table.h" + table::table(std::initializer_list l) { - int i = 0; - for (set s : l) { - this->left[s.type] = s; - } + int i = 0; + this->data.resize(l.size()); + for (set s : l) { + this->data[i] = s; + this->left[s.type] = &this->data[i]; + this->right[s.name] = &this->data[i]; + i++; + } } -table::set table::operator[](short n){ - return this->left[n]; +const table::set table::operator[](std::string s){ + return *this->right[s]; +} +const table::set table::operator[](short n){ + return *this->left[n]; +} +bool table::exists(std::string s){ + return !(right.find(s) == right.end()); } bool table::exists(short n){ - return !(left.find(n) == left.end()); + return !(left.find(n) == left.end()); +} +short table::type(std::string s){ + return this->right[s]->type; +} +std::string table::id(short n){ + return this->left[n]->id; } std::string table::name(short n){ - return this->left[n].name; + return this->left[n]->name; } diff --git a/src/table.h b/src/table.h index 377c768..128d26e 100644 --- a/src/table.h +++ b/src/table.h @@ -17,14 +17,21 @@ public: struct set { short type; F format; - std::string name; + std::string name; + std::string id; }; - table(std::initializer_list l); - set operator[](short); - bool exists(short); - std::string name(short); + table(std::initializer_list l); + const table::set operator[](std::string); + const table::set operator[](short); + bool exists(std::string); + bool exists(short); + short type(std::string); + std::string id(short); + std::string name(short); private: - std::map left; + std::vector data; + std::map left; + std::map right; }; #endif /* LOOKUPTABLE_H_ */