diff --git a/src/Lookup.h b/src/Lookup.h index 5c0fbec..c1fc08a 100644 --- a/src/Lookup.h +++ b/src/Lookup.h @@ -13,18 +13,22 @@ static table rcv_lookup = { { 1, table::STRING, "type" }, //string { 4, table::DEC, "ip_addr" }, //byte[4] { 5, table::DEC, "ip_mask" }, //byte[4] { 6, table::DEC, "gateway" }, //byte[4] - { 7, table::STRING, "firmware_version" }, //string - { 8, table::STRING, "hardware_version" }, //string + { 7, table::STRING, "firmware_version" }, + { 8, table::STRING, "hardware_version" }, { 9, table::DEC, "dhcp" }, //bool byte + { 19, table::DEC, "ports" }, //byte, maybe number of ports { 8704, table::HEX, "802.1q vlan" }, //??? + + { 12288, table::HEX, "QoS Basic 1" }, //bool = QoS Mod + { 12289, table::HEX, "QoS Basic 2" }, //QoS //{0000," "}, }; static table snd_lookup = { // TODO find out if id is unique in response - { 10, table::HEX, "???" }, //after login - { 2, table::HEX, "???" }, //after login + { 10, table::HEX, "??? - 10" }, //after login + { 2, table::HEX, "system_info" }, //page sysinfo { 512, table::STRING, "login_user" }, //string { 513, table::STRING, "new_user" }, //string { 514, table::STRING, "login_password" }, //string @@ -32,13 +36,14 @@ static table snd_lookup = { { 2200, table::HEX, "vlan" }, { 2305, table::HEX, "???" }, //sent before login and before change hostname { 4608, table::HEX, "port_trunk" }, //byte[5] last byte bitmask?? { 8192, table::HEX, "mtu_vlan" }, //byte[2] first byte bool, second byte port id - { 8449, table::HEX, "port_vlan" }, //??? - + { 8449, table::HEX, "port_vlan1" }, //??? + { 8448, table::HEX, "port_vlan2" }, //open page { 8704, table::HEX, "802.1q vlan" }, //??? get vlan / set status { 8705, table::HEX, "802.1q vlan" }, //??? { 8706, table::HEX, "802.1q vlan pvid" }, //???? - { 12288, table::HEX, "QoS Basic" }, //bool = QoS Mod + { 12288, table::HEX, "QoS Basic 1" }, //bool = QoS Mod + { 12289, table::HEX, "QoS Basic 2" }, //QoS { 16640, table::HEX, "port_mirror" }, //byte[10] second byte port id?? { 17152, table::HEX, "loop_prevention" }, //bool byte //{0000," "}, diff --git a/src/Options.h b/src/Options.h index 8921eb4..034ee3f 100644 --- a/src/Options.h +++ b/src/Options.h @@ -28,6 +28,8 @@ Login with Username and Password\n\ -f --file <path> choose a settings file\n\n\ -t --timeout <n> 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\ @@ -45,6 +47,12 @@ reboot Not yet implemented\n\ reset Not yet implemented\n\n\ ### for questions please contact <smrtlink@jdi.li> ###\n\n" +//TODO +/* + * Stdin + * socketmode + * + */ #define FLAG_HEX 1 #define FLAG_REVERSE 2 diff --git a/src/Program.cpp b/src/Program.cpp index 5776243..9b2ea33 100644 --- a/src/Program.cpp +++ b/src/Program.cpp @@ -16,6 +16,62 @@ #include "Packet.h" #include "Lookup.h" +int printHeader(Packet p) { + if (options.flags & FLAG_HEADER) { + if (options.flags & FLAG_HEX) { + std::cout << "Received Header:\n\t" << p.getHead() << "\n"; + } else { + p.printHeader(); + printf("\n"); + } + } + return 0; +} + +int printPacket(Packet p) { + if (options.flags & FLAG_HEX) { + std::cout << "Received Payload:\n\t" << p.getBody() << "\n"; + } else { + for (auto a : p.getPayload()) { + dataset d = a.second; + auto lookup = + (options.flags & FLAG_REVERSE) ? snd_lookup : rcv_lookup; + if (lookup.exists(d.type)) { + const table::set *s = lookup.get(d.type); + if (d.len > 0) { + switch (s->format) { + case table::STRING: + std::cout << std::dec << "+\t" << s->name << " = " + << &d.value[0] << std::dec << "\n"; + break; + case table::HEX: + std::cout << std::dec << "+\t" << s->name << " = " + << std::hex << d.value << std::dec << "\n"; + break; + case table::DEC: + std::cout << std::dec << "+\t" << s->name << " = " + << std::dec << d.value << std::dec << "\n"; + break; + default: + std::cout << std::dec << "+\t" << s->name << " = " + << std::hex << d.value << std::dec << "\n"; + } + } else { //empty + std::cout << std::dec << ">\t" << s->name << "\n"; + } + } else {//unknown id + if (d.len > 0) { + std::cout << "##\t" << d.type << ":\n\t"; + std::cout << std::hex << d.value << std::dec << "\n"; + } else { //empty + std::cout << "#>\t" << d.type << "\n"; + } + } + } + } + return 0; +} + int Program::list() { std::cout << "List:\n"; @@ -26,34 +82,25 @@ int Program::list() { p.encode(b); try { - boost::asio::io_service io_service; - Socket s(io_service); - s.setHostIp(host.getIp()); - s.init(DST_PORT, SRC_PORT); - s.callback = - [](Packet a) { - if (options.flags & FLAG_HEADER) { - if (options.flags & FLAG_HEX) { - std::cout <<"Received Header:\n"<< a.getHead() <<"\n"; - } else { - a.printHeader(); - std::cout<<"\n"; - } - } + 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"<<a.getBody()<<"\n"; } else { datasets d =a.getPayload(); - Switch s = Switch(); - s.parse(d); + Switch sw = Switch(); + sw.parse(d); File f; - f.write(s.toString()); - std::cout <<"Devices:\n\t"<<s.settings.hostname<<" ("<< s.device.type<<")\tMAC: "<<s.device.mac<<"\tIP: "<<s.settings.ip_addr<<"\n"; + f.write(sw.toString()); + std::cout <<"Devices:\n\t"<<sw.settings.hostname<<" ("<< sw.device.type<<")\tMAC: "<<sw.device.mac<<"\tIP: "<<sw.settings.ip_addr<<"\n"; } return 1; }; - s.send(b); - io_service.run(); + sock->send(b); + io_service->run(); } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; } @@ -67,53 +114,12 @@ int Program::sniff() { Socket s(io_service); s.setHostIp(host.getIp()); s.init(DST_PORT, SRC_PORT); - s.callback = - [](Packet p) { - std::cout <<"Packet:\n\t"<<p.opCodeToString()<<"\n"; - if (options.flags & FLAG_HEADER) { - if (options.flags & FLAG_HEX) { - std::cout <<"Received Header:\n\t"<< p.getHead() <<"\n"; - } else { - p.printHeader(); - printf("\n"); - } - } - if (options.flags & FLAG_HEX) { - std::cout <<"Received Payload:\n\t"<<p.getBody()<<"\n"; - } else { - for(auto a : p.getPayload()) { - dataset d = a.second; - auto lookup=(options.flags & FLAG_REVERSE)?snd_lookup:rcv_lookup; - if(lookup.exists(d.type)) { - if(d.len>0) { - const table::set *s = lookup.get(d.type); - switch(s->format) { - case table::STRING: - std::cout<<std::dec<<"\t"<<s->name<<": "<<&d.value[0]<<std::dec<<"\n"; - break; - case table::HEX: - std::cout<<std::dec<<"\t"<<s->name<<": "<<std::hex<<d.value<<std::dec<<"\n"; - break; - case table::DEC: - std::cout<<std::dec<<"\t"<<s->name<<": "<<std::dec<<d.value<<std::dec<<"\n"; - break; - default: - std::cout<<std::dec<<"\t"<<s->name<<": "<<std::hex<<d.value<<std::dec<<"\n"; - - } - } else { - std::cout<<std::dec<<"#"<<d.type<<"\tLength: "<<d.len<<"\n"; - std::cout<<std::hex<< "\tHex: " <<d.value<<"\n"; - d.value.push_back(0U); - std::cout<<"\tString: " <<&d.value[0]<<"\n"; - } - } else { - std::cout<<"###"<<lookup[d.type]<<"\n"; - } - } - } - return 0; - }; + s.callback = [](Packet p) { + std::cout << p.opCodeToString() << "\n"; + printHeader(p); + printPacket(p); + return 0; + }; s.listen(); io_service.run(); } catch (std::exception& e) { @@ -136,47 +142,72 @@ int Program::setProperty() { } int Program::getProperty() { - printf("Get:\n"); - Packet p = Packet(Packet::GET); - macAddr d = { 0x14, 0xcc, 0x20, 0x49, 0x5e, 0x07 }; - p.setSwitchMac(d); + std::cout << "List:\n"; + Packet p = Packet(Packet::DISCOVERY); p.setHostMac(host.getMac()); - datasets t = { { 2305, 0, { } } }; - p.setPayload(t); - bytes a = p.getBytes(); - p.encode(a); - + p.setPayload( { }); + bytes b = p.getBytes(); + p.encode(b); + std::cout << "count-x:" << sock.use_count() << "\n"; + auto s = sock; try { - boost::asio::io_service io_service; - Socket s(io_service); - s.setHostIp(host.getIp()); - s.init(DST_PORT, SRC_PORT); - s.callback = - [](Packet a) { - if (options.flags & FLAG_HEADER) { - if (options.flags & FLAG_HEX) { - std::cout <<"Received Header:\n"<< a.getHead() <<"\n"; - } else { - a.printHeader(); - std::cout<<"\n"; - } - } - if (options.flags & FLAG_HEX) { - std::cout <<"Received Payload:\n"<<a.getBody()<<"\n"; - } else { + sock->setHostIp(host.getIp()); + sock->init(DST_PORT, SRC_PORT); + + std::cout << "count-y:" << sock.use_count() << "\n"; + sock->callback = + [this](Packet a) { + auto s = sock; + std::cout<<"count-z:"<<sock.use_count()<<"\n"; + datasets d =a.getPayload(); + Switch sw = Switch(); + sw.parse(d); + std::cout <<"Devices:\n\t"<<sw.settings.hostname<<" ("<< sw.device.type<<")\tMAC: "<<sw.device.mac<<"\tIP: "<<sw.settings.ip_addr<<"\n"; + + Packet p = Packet(Packet::GET); + p.setSwitchMac(a.getSwitchMac()); + p.setHostMac(host.getMac()); + datasets t = { {2305, 0, {}}}; + p.setPayload(t); + bytes c = p.getBytes(); + p.encode(c); + sock->callback = + [this](Packet a) { + auto s = sock; datasets d =a.getPayload(); - Switch s = Switch(); - s.parse(d); - std::cout <<"Devices:\n\t"<<s.settings.hostname<<" ("<< s.device.type<<")\tMAC: "<<s.device.mac<<"\tIP: "<<s.settings.ip_addr<<"\n"; - } - return 1; + Switch sw = Switch(); + sw.parse(d); + Packet p = Packet(Packet::LOGIN); + p.setSwitchMac(a.getSwitchMac()); + p.setHostMac(host.getMac()); + datasets t = { {snd_lookup["login_user"], 0, {}}}; + p.setPayload(t); + bytes c = p.getBytes(); + p.encode(c); + + sock->callback = + [this](Packet a) { + std::cout << a.opCodeToString() << "\n"; + printHeader(a); + printPacket(a); + return 0; + }; + sock->send(c); + return 0; + }; + + std::cout<<"count-b:"<<sock.use_count()<<"\n"; + + sock->send(c); + + std::cout<<"count-a:"<<sock.use_count()<<"\n"; + return 0; }; - s.send(a); - io_service.run(); + sock->send(b); + io_service->run(); } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; } - return 1; } diff --git a/src/Program.h b/src/Program.h index bb2e7e3..1df58ec 100644 --- a/src/Program.h +++ b/src/Program.h @@ -8,12 +8,22 @@ #ifndef PROGRAM_H_ #define PROGRAM_H_ +#include <memory> + #include "Types.h" #include "Host.h" +#include "Socket.h" class Program { +private: + std::shared_ptr<boost::asio::io_service> io_service; + std::shared_ptr<Socket> sock; + Host host = Host(); public: - Program(){} + Program() { + io_service = std::make_shared<boost::asio::io_service>(); + sock = std::make_shared<Socket>(*io_service); + } void init(); int list(); int sniff(); @@ -25,8 +35,7 @@ public: int flash(); int reboot(); int reset(); -private: - Host host = Host(); + std::string input; }; #endif /* PROGRAM_H_ */ diff --git a/src/Socket.cpp b/src/Socket.cpp index dd0acdd..7ef01d4 100644 --- a/src/Socket.cpp +++ b/src/Socket.cpp @@ -18,6 +18,8 @@ Socket::Socket(boost::asio::io_service& io_service) : } //, resolver( io_service) void Socket::init(short dst_port, short src_port) { + if (initialized) + return; if (options.flags & FLAG_REVERSE) { short p = dst_port; @@ -28,6 +30,7 @@ void Socket::init(short dst_port, short src_port) { if (options.flags & FLAG_DEBUG) std::cout << "Local IP:\t" << local_ip << "\n"; + wildcard_endpoint_ = boost::asio::ip::udp::endpoint( boost::asio::ip::address_v4::from_string("0.0.0.0"), src_port); local_endpoint_ = boost::asio::ip::udp::endpoint( @@ -57,6 +60,8 @@ void Socket::init(short dst_port, short src_port) { } }); } + + initialized = 1; } void Socket::setHostIp(ipAddr ip) { @@ -87,7 +92,6 @@ void Socket::listen() { Packet p = Packet(Packet::RETURN); p.encode(data); p.parse(data); - datasets l = p.getPayload(); if(!callback(p)) { //TODO do something } diff --git a/src/Socket.h b/src/Socket.h index bab3998..6bda28a 100644 --- a/src/Socket.h +++ b/src/Socket.h @@ -26,7 +26,7 @@ public: void send(bytes); void listen(); void setHostIp(ipAddr); - int (*callback)(Packet)=[](Packet a) { + std::function<int(Packet)> callback = [](Packet a) { return 0; }; @@ -40,6 +40,7 @@ private: boost::asio::deadline_timer timer; bytes data = bytes(MAX_LENGTH); ipAddr local_ip; + int initialized = 0; }; diff --git a/src/smrtlink.cpp b/src/smrtlink.cpp index e8f8984..c23c0a0 100644 --- a/src/smrtlink.cpp +++ b/src/smrtlink.cpp @@ -8,6 +8,7 @@ #include <cstring> #include <iostream> +#include <sstream> #include <string> #include <cstdlib> #include <cstdio> @@ -113,6 +114,12 @@ int main(int argc, char *argv[]) { } } + /*//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]);